[llvm] [Aarch64] Add missing earlyclobber to sqrshr and uqrshl instructions. (PR #77782)

Alfie Richards via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 11 10:00:13 PST 2024


https://github.com/AlfieRichardsArm updated https://github.com/llvm/llvm-project/pull/77782

>From 60f722249fbae5f05d0256f0bf1339ffe8eb678e Mon Sep 17 00:00:00 2001
From: Alfie Richards <alfie.richards at arm.com>
Date: Wed, 10 Jan 2024 16:05:02 +0000
Subject: [PATCH 1/2] [Aarch64] Add missing earlyclobber to sqrshr and uqrshl
 instructions.

This avoids possible undefined behaviour using the same register
for Rm and Rda.

Additionally adds a check in MC to produce an error upon parsing
this case.
---
 llvm/lib/Target/ARM/ARMInstrMVE.td            |  2 +-
 .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp |  8 +++++++
 .../AArch64/sqrshr-uqrshl-unpredictable.ll    | 21 +++++++++++++++++++
 .../AArch64/mve-sqrshr-uqrshl-earlyclobber.s  |  6 ++++++
 4 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/AArch64/sqrshr-uqrshl-unpredictable.ll
 create mode 100644 llvm/test/MC/AArch64/mve-sqrshr-uqrshl-earlyclobber.s

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..f666c028b9d09c 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

>From 42889a0ccc95f648fb0c47d4bacc7fd29bcb0b01 Mon Sep 17 00:00:00 2001
From: Alfie Richards <alfie.richards at arm.com>
Date: Thu, 11 Jan 2024 17:59:03 +0000
Subject: [PATCH 2/2] Move sqrshr-uqrshl-unpredictable.ll test to
 llvm/test/CodeGen/ARM

---
 llvm/test/CodeGen/{AArch64 => ARM}/sqrshr-uqrshl-unpredictable.ll | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename llvm/test/CodeGen/{AArch64 => ARM}/sqrshr-uqrshl-unpredictable.ll (100%)

diff --git a/llvm/test/CodeGen/AArch64/sqrshr-uqrshl-unpredictable.ll b/llvm/test/CodeGen/ARM/sqrshr-uqrshl-unpredictable.ll
similarity index 100%
rename from llvm/test/CodeGen/AArch64/sqrshr-uqrshl-unpredictable.ll
rename to llvm/test/CodeGen/ARM/sqrshr-uqrshl-unpredictable.ll



More information about the llvm-commits mailing list