Open tschuett opened 4 months ago
@llvm/issue-subscribers-backend-aarch64
Author: Thorsten Schütt (tschuett)
It tries to unmerge a vector into smaller vectors:
%6:_(<2 x s64>), %7:_(<2 x s64>) = G_UNMERGE_VALUES %5:_(<4 x p0>)
It should have used G_EXTRACT_VECTOR_ELT to build two G_BUILD_VECTOR s.
In AArch64Lowering there seems to be no buildUnmerge invocation. The generic CallLowering has many buildUnmerge calls.
Maybe, this a target independent issue?!?.
The real issue seems to s64 vs p0.
Just asking what is s64
and p0
. Do you have a pointer to the ref defining those types ? Are there types equivalent for size_t
and void*
?
They are instances of LLT. s64 is a scalar with 64 bit. P0 is a pointer in address space 0.
They are both instances of LLT with 64 bit, but they are not the same. The G_UNMERGE_VALUES fails because the input are P0s and the output are s64s.
I put asserts into buildUnmerge. Assuming I got it right, this might be a stack trace of the issue:
#7 0x000000010514500c llvm::MachineIRBuilder::buildUnmerge(llvm::ArrayRef<llvm::Register>, llvm::SrcOp const&)
#8 0x0000000105051260 llvm::CallLowering::handleAssignments(llvm::CallLowering::ValueHandler&, llvm::SmallVectorImpl<llvm::CallLowering::ArgInfo>&, llvm::CCState&, llvm::SmallVectorImpl<llvm::CCValAssign>&, llvm::MachineIRBuilder&, llvm::ArrayRef<llvm::Register>) const
#9 0x000000010504ffb6 llvm::CallLowering::determineAndHandleAssignments(llvm::CallLowering::ValueHandler&, llvm::CallLowering::ValueAssigner&, llvm::SmallVectorImpl<llvm::CallLowering::ArgInfo>&, llvm::MachineIRBuilder&, unsigned int, bool, llvm::ArrayRef<llvm::Register>) const
#10 0x0000000102871b02 llvm::AArch64CallLowering::lowerReturn(llvm::MachineIRBuilder&, llvm::Value const*, llvm::ArrayRef<llvm::Register>, llvm::FunctionLoweringInfo&, llvm::Register) const
#11 0x00000001050a4cb6 llvm::IRTranslator::translateRet(llvm::User const&, llvm::MachineIRBuilder&)
handleAssignments calls buildCopyToRegs, which is static. The latter calls getGCDType, which does not distinguish between scalars and pointers.
and there are B.buildUnmerge calls in buildCopyToRegs
I may be wrong, but I believe that this is the buggy code.
LLT GCDTy = getGCDType(SrcTy, PartTy); if (GCDTy == PartTy) { // If this already evenly divisible, we can create a simple unmerge. B.buildUnmerge(DstRegs, SrcReg); return; }
getGCDType should be fallible when the scalar types don't match: p0 vs. s64.
Do you want to ptrtoint or assign pointer vectors to registers?
@arsenm @aemerson @davemgreen
ptrtoint might be not enough. What happens with 256bit funny float vectors that you want to return?
getGCDType should be fallible when the scalar types don't match: p0 vs. s64.
Do you mean do match? Part of the point of this was to handle unmerging pointers to smaller scalars
Or an alternative path where the scalar types don't match.
if (SrcTy.isVector() && PartTy.isVector() && GCD && SrcTy.getScalarType() != PartTy.getScalarType()) {
// bicast + unmerge
}
Part of the point of this was to handle unmerging pointers to smaller scalars
This is exactly the error that we get. We cannot unmerge pointers into scalars.
Once LLT supports floats , there will be more cases:
enum class UnMergeKind {
False,
True,
WithBitcast
};
UnMergeKind isUnmergeable(unsigned NrOfDstRegs, LLT PartTy, LLT SrcTy);
Part of the point of this was to handle unmerging pointers to smaller scalars
This is exactly the error that we get. We cannot unmerge pointers into scalars.
Yes you can. AMDGPU heavily relies on unmerging pointers into pairs of s32
Look at the example at the top. The MachineVerifier complained.
Look at the example at the top. The MachineVerifier complained.
It's an oddity, but we currently support pointer-> scalar, but not vector of pointers -> vector of scalars
It tries to unmerge into vectors and translates p0 into s64.
LLVM IR:
call:
Error: