[llvm] a4796b1 - [ARM] Emit error message when incompatible reg is specified (#147559)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 24 10:19:29 PDT 2025
Author: eleviant
Date: 2025-07-24T19:19:25+02:00
New Revision: a4796b14fcf3bf2749dcb90b5c870140f1a82f78
URL: https://github.com/llvm/llvm-project/commit/a4796b14fcf3bf2749dcb90b5c870140f1a82f78
DIFF: https://github.com/llvm/llvm-project/commit/a4796b14fcf3bf2749dcb90b5c870140f1a82f78.diff
LOG: [ARM] Emit error message when incompatible reg is specified (#147559)
At the moment the following piece of code causes undefined behavior:
```
int a;
void b() {
register float d2 asm("d2") = a;
asm("" ::"r"(d2));
}
```
This happens because variable and register types are incompatible.
Added:
llvm/test/CodeGen/ARM/bad-constraint.ll
llvm/test/CodeGen/ARM/inlineasm-int-to-float.ll
Modified:
llvm/lib/Target/ARM/ARMISelLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 8b7f06a5b5014..fca5dff092306 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20347,6 +20347,13 @@ ARMTargetLowering::getSingleConstraintMatchWeight(
return weight;
}
+static bool isIncompatibleReg(const MCPhysReg &PR, MVT VT) {
+ if (PR == 0 || VT == MVT::Other)
+ return false;
+ return (ARM::SPRRegClass.contains(PR) && VT != MVT::f32 && VT != MVT::i32) ||
+ (ARM::DPRRegClass.contains(PR) && VT != MVT::f64);
+}
+
using RCPair = std::pair<unsigned, const TargetRegisterClass *>;
RCPair ARMTargetLowering::getRegForInlineAsmConstraint(
@@ -20420,7 +20427,10 @@ RCPair ARMTargetLowering::getRegForInlineAsmConstraint(
if (StringRef("{cc}").equals_insensitive(Constraint))
return std::make_pair(unsigned(ARM::CPSR), &ARM::CCRRegClass);
- return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
+ auto RCP = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
+ if (isIncompatibleReg(RCP.first, VT))
+ return {0, nullptr};
+ return RCP;
}
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
diff --git a/llvm/test/CodeGen/ARM/bad-constraint.ll b/llvm/test/CodeGen/ARM/bad-constraint.ll
new file mode 100644
index 0000000000000..9b8fcd576db5d
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/bad-constraint.ll
@@ -0,0 +1,25 @@
+; RUN: not llc -filetype=obj %s -o /dev/null 2>&1 | FileCheck %s
+; CHECK: error: couldn't allocate input reg for constraint '{d2}'
+; CHECK-NEXT: error: couldn't allocate input reg for constraint '{s2}'
+
+target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv8a-unknown-linux-gnueabihf"
+
+ at a = local_unnamed_addr global i32 0, align 4
+
+define void @_Z1bv() local_unnamed_addr {
+entry:
+ %0 = load i32, ptr @a, align 4
+ %conv = sext i32 %0 to i64
+ tail call void asm sideeffect "", "{d2}"(i64 %conv)
+ ret void
+}
+
+define void @_Z1cv() local_unnamed_addr {
+entry:
+ %0 = load i32, ptr @a, align 4
+ %conv = sext i32 %0 to i64
+ tail call void asm sideeffect "", "{s2}"(i64 %conv)
+ ret void
+}
+
diff --git a/llvm/test/CodeGen/ARM/inlineasm-int-to-float.ll b/llvm/test/CodeGen/ARM/inlineasm-int-to-float.ll
new file mode 100644
index 0000000000000..1c301b6763138
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/inlineasm-int-to-float.ll
@@ -0,0 +1,17 @@
+; RUN: llc -filetype=asm %s -o - | FileCheck %s
+
+; CHECK: movw r0, :lower16:a
+; CHECK-NEXT: movt r0, :upper16:a
+; CHECK-NEXT: vldr s6, [r0]
+
+target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv8a-unknown-linux-gnueabihf"
+
+ at a = local_unnamed_addr global i32 0, align 4
+
+define void @_Z1dv() local_unnamed_addr {
+entry:
+ %0 = load i32, ptr @a, align 4
+ tail call void asm sideeffect "", "{s6}"(i32 %0)
+ ret void
+}
More information about the llvm-commits
mailing list