Author: David Sherwood Date: 2020-12-08T13:48:43Z New Revision: 59f17b57d9c9abf86d8dcc05c49d3bbd807e29c7
URL: https://github.com/llvm/llvm-project/commit/59f17b57d9c9abf86d8dcc05c49d3bbd807e29c7 DIFF: https://github.com/llvm/llvm-project/commit/59f17b57d9c9abf86d8dcc05c49d3bbd807e29c7.diff LOG: [SVE] Fix crashes with inline assembly All the crashes found compiling inline assembly are fixed in this patch by changing AArch64TargetLowering::getRegForInlineAsmConstraint to be more resilient to mismatched value and register types. For example, it makes no sense to request a predicate register for a nxv2i64 type and so on. Tests have been added here: test/CodeGen/AArch64/inline-asm-constraints-bad-sve.ll Differential Revision: https://reviews.llvm.org/D92554 Added: llvm/test/CodeGen/AArch64/inline-asm-constraints-bad-sve.ll Modified: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp Removed: ################################################################################ diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index cca31a701d56..700c281cdaa9 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7511,23 +7511,30 @@ AArch64TargetLowering::getRegForInlineAsmConstraint( if (Constraint.size() == 1) { switch (Constraint[0]) { case 'r': - if (VT.getSizeInBits() == 64) + if (VT.isScalableVector()) + return std::make_pair(0U, nullptr); + if (VT.getFixedSizeInBits() == 64) return std::make_pair(0U, &AArch64::GPR64commonRegClass); return std::make_pair(0U, &AArch64::GPR32commonRegClass); - case 'w': + case 'w': { if (!Subtarget->hasFPARMv8()) break; - if (VT.isScalableVector()) - return std::make_pair(0U, &AArch64::ZPRRegClass); - if (VT.getSizeInBits() == 16) + if (VT.isScalableVector()) { + if (VT.getVectorElementType() != MVT::i1) + return std::make_pair(0U, &AArch64::ZPRRegClass); + return std::make_pair(0U, nullptr); + } + uint64_t VTSize = VT.getFixedSizeInBits(); + if (VTSize == 16) return std::make_pair(0U, &AArch64::FPR16RegClass); - if (VT.getSizeInBits() == 32) + if (VTSize == 32) return std::make_pair(0U, &AArch64::FPR32RegClass); - if (VT.getSizeInBits() == 64) + if (VTSize == 64) return std::make_pair(0U, &AArch64::FPR64RegClass); - if (VT.getSizeInBits() == 128) + if (VTSize == 128) return std::make_pair(0U, &AArch64::FPR128RegClass); break; + } // The instructions that this constraint is designed for can // only take 128-bit registers so just use that regclass. case 'x': @@ -7548,10 +7555,11 @@ AArch64TargetLowering::getRegForInlineAsmConstraint( } else { PredicateConstraint PC = parsePredicateConstraint(Constraint); if (PC != PredicateConstraint::Invalid) { - assert(VT.isScalableVector()); + if (!VT.isScalableVector() || VT.getVectorElementType() != MVT::i1) + return std::make_pair(0U, nullptr); bool restricted = (PC == PredicateConstraint::Upl); return restricted ? std::make_pair(0U, &AArch64::PPR_3bRegClass) - : std::make_pair(0U, &AArch64::PPRRegClass); + : std::make_pair(0U, &AArch64::PPRRegClass); } } if (StringRef("{cc}").equals_lower(Constraint)) diff --git a/llvm/test/CodeGen/AArch64/inline-asm-constraints-bad-sve.ll b/llvm/test/CodeGen/AArch64/inline-asm-constraints-bad-sve.ll new file mode 100644 index 000000000000..5a2f4746af87 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/inline-asm-constraints-bad-sve.ll @@ -0,0 +1,29 @@ +; RUN: not llc -mtriple=aarch64-none-linux-gnu -mattr=+sve -o - %s 2>&1 | FileCheck %s + +target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-linux-gnu" + +; CHECK: error: couldn't allocate input reg for constraint 'Upa' +; CHECK: error: couldn't allocate input reg for constraint 'r' +; CHECK: error: couldn't allocate output register for constraint 'w' + +define <vscale x 16 x i1> @foo1(i32 *%in) { +entry: + %0 = load i32, i32* %in, align 4 + %1 = call <vscale x 16 x i1> asm sideeffect "mov $0.b, $1.b \0A", "=@3Upa,@3Upa"(i32 %0) + ret <vscale x 16 x i1> %1 +} + +define <vscale x 4 x float> @foo2(<vscale x 4 x i32> *%in) { +entry: + %0 = load <vscale x 4 x i32>, <vscale x 4 x i32>* %in, align 16 + %1 = call <vscale x 4 x float> asm sideeffect "ptrue p0.s, #1 \0Afabs $0.s, p0/m, $1.s \0A", "=w,r"(<vscale x 4 x i32> %0) + ret <vscale x 4 x float> %1 +} + +define <vscale x 16 x i1> @foo3(<vscale x 16 x i1> *%in) { +entry: + %0 = load <vscale x 16 x i1>, <vscale x 16 x i1>* %in, align 2 + %1 = call <vscale x 16 x i1> asm sideeffect "mov $0.b, $1.b \0A", "=&w,w"(<vscale x 16 x i1> %0) + ret <vscale x 16 x i1> %1 +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits