[llvm] 3e64f8a - [AArch64][CodeGen] Fix illegal register aliasing bug for mops instrs (#88869)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 18 02:53:28 PDT 2024


Author: Nashe Mncube
Date: 2024-04-18T10:53:23+01:00
New Revision: 3e64f8a4e74cdcaf5920879c86e7e0a827f6ec13

URL: https://github.com/llvm/llvm-project/commit/3e64f8a4e74cdcaf5920879c86e7e0a827f6ec13
DIFF: https://github.com/llvm/llvm-project/commit/3e64f8a4e74cdcaf5920879c86e7e0a827f6ec13.diff

LOG: [AArch64][CodeGen] Fix illegal register aliasing bug for mops instrs (#88869)

A bug was found where mops instructions were being generated that
aliased the source and size registers. This is unpredictable behaviour.
This patch uses the earlyclobber constraint on the input source
register so that it doesn't alias with the size register. Also a test is
introduced which checks affected instructions can't violate this
constraint.

Added: 
    llvm/test/CodeGen/AArch64/mops-register-alias.ll
    llvm/test/MC/AArch64/armv9.3a-mops-register-aliasing.s

Modified: 
    llvm/lib/Target/AArch64/AArch64InstrInfo.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index e1624f70185e1e..3bf90778363c6c 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -9486,7 +9486,7 @@ let Predicates = [HasMOPS], Defs = [NZCV], Size = 12, mayStore = 1 in {
   let mayLoad = 0 in {
     def MOPSMemorySetPseudo  : Pseudo<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb),
                                       (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm),
-                                      [], "$Rd = $Rd_wb,$Rn = $Rn_wb">, Sched<[]>;
+                                      [], "$Rd = $Rd_wb,$Rn = $Rn_wb, at earlyclobber $Rn_wb">, Sched<[]>;
   }
 }
 let Predicates = [HasMOPS, HasMTE], Defs = [NZCV], Size = 12, mayLoad = 0, mayStore = 1 in {

diff  --git a/llvm/test/CodeGen/AArch64/mops-register-alias.ll b/llvm/test/CodeGen/AArch64/mops-register-alias.ll
new file mode 100644
index 00000000000000..855ab959c4e76b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/mops-register-alias.ll
@@ -0,0 +1,21 @@
+; RUN: llc -O1 -mtriple=aarch64-none-linux-gnu -mattr=+mops -o - %s  | FileCheck %s
+
+define void @call_memset_intrinsic() #0 {
+; CHECK-LABEL: call_memset_intrinsic:
+; CHECK:       // %bb.0: // %entry
+; CHECK:         setp [x{{[0-9]+}}]!, x{{[0-9]+}}!, x{{[0-9]+}}
+; CHECK-NOT:     setp [x{{[0-9]+}}]!, x[[REG:[0-9]+]]!, x[[REG]]
+; CHECK-NEXT:    setm [x{{[0-9]+}}]!, x{{[0-9]+}}!, x{{[0-9]+}}
+; CHECK-NOT:     setm [x{{[0-9]+}}]!, x[[REG:[0-9]+]]!, x[[REG]]
+; CHECK-NEXT:    sete [x{{[0-9]+}}]!, x{{[0-9]+}}!, x{{[0-9]+}}
+; CHECK-NOT:     sete [x{{[0-9]+}}]!, x[[REG:[0-9]+]]!, x[[REG]]
+entry:
+
+    %V0 = alloca [65 x i8], align 1
+    call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(64) %V0, i8 64, i64 64, i1 false)
+    %add.ptr = getelementptr inbounds i8, ptr %V0, i64 64
+     call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(64) %add.ptr, i8 64, i64 64, i1 false)
+    ret void
+}
+
+attributes #0 = { "target-cpu"="generic" "target-features"="+mops,+strict-align,+v9.3a" }

diff  --git a/llvm/test/MC/AArch64/armv9.3a-mops-register-aliasing.s b/llvm/test/MC/AArch64/armv9.3a-mops-register-aliasing.s
new file mode 100644
index 00000000000000..109b33857a9d2d
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv9.3a-mops-register-aliasing.s
@@ -0,0 +1,15 @@
+// RUN: not llvm-mc -triple aarch64 -mattr=+mops < %s 2>&1 | FileCheck %s
+
+  setp  [x0]!, x1!, x1
+  setm  [x0]!, x1!, x1
+  sete  [x0]!, x1!, x1
+
+// CHECK:      error: invalid SET instruction, source and size registers are the same
+// CHECK-NEXT:   setp  [x0]!, x1!, x1
+// CHECK-NEXT:         ^
+// CHECK-NEXT: error: invalid SET instruction, source and size registers are the same
+// CHECK-NEXT:   setm  [x0]!, x1!, x1
+// CHECK-NEXT:         ^
+// CHECK-NEXT: error: invalid SET instruction, source and size registers are the same
+// CHECK-NEXT:   sete  [x0]!, x1!, x1
+// CHECK-NEXT:         ^


        


More information about the llvm-commits mailing list