[llvm] 60c7757 - [ARM] Add missing earlyclobber to sqrshr and uqrshl instructions. (#77782)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 16 02:30:20 PST 2024


Author: Alfie Richards
Date: 2024-01-16T10:30:16Z
New Revision: 60c775769b0ee8f57a41c0667664afb12958eeac

URL: https://github.com/llvm/llvm-project/commit/60c775769b0ee8f57a41c0667664afb12958eeac
DIFF: https://github.com/llvm/llvm-project/commit/60c775769b0ee8f57a41c0667664afb12958eeac.diff

LOG: [ARM] Add missing earlyclobber to sqrshr and uqrshl instructions. (#77782)

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.

Added: 
    llvm/test/CodeGen/ARM/sqrshr-uqrshl-unpredictable.ll
    llvm/test/MC/ARM/mve-sqrshr-uqrshl-earlyclobber.s

Modified: 
    llvm/lib/Target/ARM/ARMInstrMVE.td
    llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td
index fa25c571a9bd5ef..12c3968b9cecea4 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 a91dd24a9056a9a..e534f1f7146dcc3 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/ARM/sqrshr-uqrshl-unpredictable.ll b/llvm/test/CodeGen/ARM/sqrshr-uqrshl-unpredictable.ll
new file mode 100644
index 000000000000000..d393a474dfa63ac
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/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/ARM/mve-sqrshr-uqrshl-earlyclobber.s b/llvm/test/MC/ARM/mve-sqrshr-uqrshl-earlyclobber.s
new file mode 100644
index 000000000000000..3b78b826538f77d
--- /dev/null
+++ b/llvm/test/MC/ARM/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


        


More information about the llvm-commits mailing list