From 8000e7a0c3cf6c9c83fac6acc80a11b5e49f9b3b Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Mon, 6 Feb 2017 21:57:06 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294248 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AArch64/AArch64GenRegisterBankInfo.def | 47 ++++++++++--------- .../AArch64/AArch64RegisterBankInfo.cpp | 12 +++-- lib/Target/AArch64/AArch64RegisterBankInfo.h | 9 ++-- .../AArch64/GlobalISel/arm64-fallback.ll | 8 ++++ 4 files changed, 48 insertions(+), 28 deletions(-) diff --git a/lib/Target/AArch64/AArch64GenRegisterBankInfo.def b/lib/Target/AArch64/AArch64GenRegisterBankInfo.def index ea46a0a5da8..8b1c9740d2a 100644 --- a/lib/Target/AArch64/AArch64GenRegisterBankInfo.def +++ b/lib/Target/AArch64/AArch64GenRegisterBankInfo.def @@ -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"); diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index de04d343c23..20a5979f9b4 100644 --- a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -536,9 +536,15 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { RegisterBankInfo::InstructionMapping Mapping = InstructionMapping{DefaultMappingID, Cost, nullptr, NumOperands}; SmallVector 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; diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.h b/lib/Target/AArch64/AArch64RegisterBankInfo.h index bc609f422ac..0a795a42c0b 100644 --- a/lib/Target/AArch64/AArch64RegisterBankInfo.h +++ b/lib/Target/AArch64/AArch64RegisterBankInfo.h @@ -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 }; diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll b/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll index 84f2a1c6e70..96ec2152725 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll @@ -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 +} -- 2.50.1