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

Nashe Mncube via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 16 03:30:09 PDT 2024


https://github.com/nasherm created https://github.com/llvm/llvm-project/pull/88869

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


>From f224e69d2a6a76ff967f83956f9f0a4453a04079 Mon Sep 17 00:00:00 2001
From: nasmnc01 <nashe.mncube at arm.com>
Date: Tue, 16 Apr 2024 10:34:09 +0100
Subject: [PATCH] [AArch64][CodeGen] Fix illegal register aliasing bug for mops
 instrs

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

Change-Id: I1e608bfbf97d135cdfd86d04a8d70510854ce2ca
---
 llvm/lib/Target/AArch64/AArch64InstrInfo.td       |  2 +-
 .../MC/AArch64/armv9.3a-mops-register-aliasing.s  | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/MC/AArch64/armv9.3a-mops-register-aliasing.s

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/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