[llvm] [Aarch64] Add missing earlyclobber to sqrshr and uqrshl instructions. (PR #77782)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 11 07:18:06 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: None (AlfieRichardsArm)
<details>
<summary>Changes</summary>
This avoids possible undefined behavior using the same register for Rm and Rda.
Additionally adds a check in MC to produce an error upon parsing this case.
---
Full diff: https://github.com/llvm/llvm-project/pull/77782.diff
4 Files Affected:
- (modified) llvm/lib/Target/ARM/ARMInstrMVE.td (+1-1)
- (modified) llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (+8)
- (added) llvm/test/CodeGen/AArch64/sqrshr-uqrshl-unpredictable.ll (+21)
- (added) llvm/test/MC/AArch64/mve-sqrshr-uqrshl-earlyclobber.s (+6)
``````````diff
diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td
index fa25c571a9bd5e..12c3968b9cecea 100644
--- a/llvm/lib/Target/ARM/ARMInstrMVE.td
+++ b/llvm/lib/Target/ARM/ARMInstrMVE.td
@@ -478,7 +478,7 @@ def MVE_URSHR : MVE_ScalarShiftSRegImm<"urshr", 0b01>;
class MVE_ScalarShiftSRegReg<string iname, bits<2> op5_4>
: MVE_ScalarShiftSingleReg<iname, (ins rGPR:$RdaSrc, rGPR:$Rm),
- "$RdaSrc, $Rm", "$RdaDest = $RdaSrc",
+ "$RdaSrc, $Rm", "@earlyclobber $RdaDest,$RdaDest = $RdaSrc",
[(set rGPR:$RdaDest,
(i32 (!cast<Intrinsic>("int_arm_mve_" # iname)
(i32 rGPR:$RdaSrc), (i32 rGPR:$Rm))))]> {
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 18dccb26b87769..7414b5307f704c 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -8308,6 +8308,14 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
return Error (Operands[3]->getStartLoc(), "Q-register indexes must be 2 and 0 or 3 and 1");
break;
}
+ case ARM::MVE_SQRSHR:
+ case ARM::MVE_UQRSHL: {
+ if (Operands[2]->getReg() == Operands[3]->getReg()) {
+ return Error (Operands[2]->getStartLoc(),
+ "Rda register and Rm register can't be identical");
+ }
+ break;
+ }
case ARM::UMAAL:
case ARM::UMLAL:
case ARM::UMULL:
diff --git a/llvm/test/CodeGen/AArch64/sqrshr-uqrshl-unpredictable.ll b/llvm/test/CodeGen/AArch64/sqrshr-uqrshl-unpredictable.ll
new file mode 100644
index 00000000000000..d393a474dfa63a
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sqrshr-uqrshl-unpredictable.ll
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple armv8.1m.main -mattr=+mve %s -o - | FileCheck %s
+
+; Check that we don't create an unpredictable sqrshr or uqrshl instruction,
+; e.g. sqrshr r0, r0
+
+declare i32 @llvm.arm.mve.sqrshr(i32, i32) #1
+declare i32 @llvm.arm.mve.uqrshl(i32, i32) #1
+
+define i32 @sqrshr() #0 {
+; CHECK-LABEL: sqrshr
+; CHECK-NOT: sqrshr r[[REG:[0-9]+]], r[[REG]]
+ %1 = tail call i32 @llvm.arm.mve.sqrshr(i32 1, i32 1)
+ ret i32 %1
+}
+
+define i32 @uqrshl() #0 {
+; CHECK-LABEL: uqrshl
+; CHECK-NOT: uqrshl r[[REG:[0-9]+]], r[[REG]]
+ %1 = tail call i32 @llvm.arm.mve.uqrshl(i32 1, i32 1)
+ ret i32 %1
+}
diff --git a/llvm/test/MC/AArch64/mve-sqrshr-uqrshl-earlyclobber.s b/llvm/test/MC/AArch64/mve-sqrshr-uqrshl-earlyclobber.s
new file mode 100644
index 00000000000000..3b78b826538f77
--- /dev/null
+++ b/llvm/test/MC/AArch64/mve-sqrshr-uqrshl-earlyclobber.s
@@ -0,0 +1,6 @@
+@ RUN: not llvm-mc -triple armv8.1m.main -mattr=+mve < %s 2>&1 | FileCheck %s
+
+ sqrshr r1, r1
+@ CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Rda register and Rm register can't be identical
+ uqrshl r1, r1
+@ CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Rda register and Rm register can't be identical
``````````
</details>
https://github.com/llvm/llvm-project/pull/77782
More information about the llvm-commits
mailing list