GlobalISel: fall back gracefully when we can't map an operand's size.

AArch64 was asserting when it was asked to provide a register-bank of a size it
couldn't deal with (in this case an s128 IMPLICIT_DEF). But we want a robust
fallback path so this isn't allowed.

llvm-svn: 294248
This commit is contained in:
Tim Northover 2017-02-06 21:57:06 +00:00
parent 0e6afbdd77
commit 6f2db57dae
4 changed files with 48 additions and 28 deletions

View File

@ -37,57 +37,59 @@ RegisterBankInfo::PartialMapping AArch64GenRegisterBankInfo::PartMappings[]{
// ValueMappings.
RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{
/* BreakDown, NumBreakDowns */
// 0: invalid
{nullptr, 0},
// 3-operands instructions (all binary operations should end up with one of
// those mapping).
// 0: FPR 32-bit value. <-- This must match First3OpsIdx.
// 1: FPR 32-bit value. <-- This must match First3OpsIdx.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
// 3: FPR 64-bit value.
// 4: FPR 64-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
// 6: FPR 128-bit value.
// 7: FPR 128-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
// 9: FPR 256-bit value.
// 10: FPR 256-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
// 12: FPR 512-bit value.
// 13: FPR 512-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
// 15: GPR 32-bit value.
// 16: GPR 32-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
// 18: GPR 64-bit value. <-- This must match Last3OpsIdx.
// 19: GPR 64-bit value. <-- This must match Last3OpsIdx.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
// Cross register bank copies.
// 21: FPR 32-bit value to GPR 32-bit value. <-- This must match
// 22: FPR 32-bit value to GPR 32-bit value. <-- This must match
// FirstCrossRegCpyIdx.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
// 23: FPR 64-bit value to GPR 64-bit value.
// 24: FPR 64-bit value to GPR 64-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
// 25: FPR 128-bit value to GPR 128-bit value (invalid)
// 26: FPR 128-bit value to GPR 128-bit value (invalid)
{nullptr, 1},
{nullptr, 1},
// 27: FPR 256-bit value to GPR 256-bit value (invalid)
// 28: FPR 256-bit value to GPR 256-bit value (invalid)
{nullptr, 1},
{nullptr, 1},
// 29: FPR 512-bit value to GPR 512-bit value (invalid)
// 30: FPR 512-bit value to GPR 512-bit value (invalid)
{nullptr, 1},
{nullptr, 1},
// 31: GPR 32-bit value to FPR 32-bit value.
// 32: GPR 32-bit value to FPR 32-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
// 33: GPR 64-bit value to FPR 64-bit value. <-- This must match
// 34: GPR 64-bit value to FPR 64-bit value. <-- This must match
// LastCrossRegCpyIdx.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
@ -144,7 +146,7 @@ unsigned AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(unsigned RBIdx,
return 0;
if (Size <= 64)
return 1;
llvm_unreachable("Unexpected size");
return -1;
}
if (RBIdx == PMI_FirstFPR) {
if (Size <= 32)
@ -157,19 +159,22 @@ unsigned AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(unsigned RBIdx,
return 3;
if (Size <= 512)
return 4;
llvm_unreachable("Unexpected size");
return -1;
}
llvm_unreachable("Unexpected bank");
return -1;
}
const RegisterBankInfo::ValueMapping *
AArch64GenRegisterBankInfo::getValueMapping(PartialMappingIdx RBIdx,
unsigned Size) {
assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that");
unsigned ValMappingIdx = First3OpsIdx +
(RBIdx - PartialMappingIdx::PMI_Min +
getRegBankBaseIdxOffset(RBIdx, Size)) *
ValueMappingIdx::DistanceBetweenRegBanks;
unsigned BaseIdxOffset = getRegBankBaseIdxOffset(RBIdx, Size);
if (BaseIdxOffset == -1u)
return &ValMappings[InvalidIdx];
unsigned ValMappingIdx =
First3OpsIdx + (RBIdx - PartialMappingIdx::PMI_Min + BaseIdxOffset) *
ValueMappingIdx::DistanceBetweenRegBanks;
assert(ValMappingIdx >= First3OpsIdx && ValMappingIdx <= Last3OpsIdx &&
"Mapping out of bound");

View File

@ -536,9 +536,15 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
RegisterBankInfo::InstructionMapping Mapping =
InstructionMapping{DefaultMappingID, Cost, nullptr, NumOperands};
SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
for (unsigned Idx = 0; Idx < NumOperands; ++Idx)
if (MI.getOperand(Idx).isReg())
OpdsMapping[Idx] = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
if (MI.getOperand(Idx).isReg()) {
auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
if (!Mapping->isValid())
return InstructionMapping();
OpdsMapping[Idx] = Mapping;
}
}
Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
return Mapping;

View File

@ -47,11 +47,12 @@ protected:
static PartialMappingIdx BankIDToCopyMapIdx[];
enum ValueMappingIdx {
First3OpsIdx = 0,
Last3OpsIdx = 18,
InvalidIdx = 0,
First3OpsIdx = 1,
Last3OpsIdx = 19,
DistanceBetweenRegBanks = 3,
FirstCrossRegCpyIdx = 21,
LastCrossRegCpyIdx = 33,
FirstCrossRegCpyIdx = 22,
LastCrossRegCpyIdx = 34,
DistanceBetweenCrossRegCpy = 2
};

View File

@ -82,3 +82,11 @@ define void @legal_default([8 x i8] %in) {
insertvalue { [4 x i8], [8 x i8], [4 x i8] } undef, [8 x i8] %in, 1
ret void
}
; AArch64 was asserting instead of returning an invalid mapping for unknown
; sizes.
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for sequence_sizes
; FALLBACK-WITH-REPORT-LABEL: sequence_sizes:
define i128 @sequence_sizes([8 x i8] %in) {
ret i128 undef
}