[llvm] AArch64/GlobalISel: Mark the MOPS pseudo NZCV def dead (PR #227643)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 03:19:17 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/227643

AArch64/GlobalISel: Mark the MOPS pseudo NZCV def dead

Co-authored-by: Claude Opus 5 <noreply at anthropic.com>

Remove test

>From 37e3866b9ff4c43f1749558dd6efb1116b350c49 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 29 Sep 2026 00:32:35 +0200
Subject: [PATCH 1/2] AArch64/GlobalISel: Mark the MOPS pseudo NZCV def dead

Co-authored-by: Claude Opus 5 <noreply at anthropic.com>
---
 .../GISel/AArch64InstructionSelector.cpp      |  7 +-
 llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll   | 72 +++++++++++++++++++
 2 files changed, 77 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 22c0e3a3a462d..96f932e71dbd0 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -3665,11 +3665,13 @@ bool AArch64InstructionSelector::selectMOPS(MachineInstr &GI,
   Register DefSize = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
   if (IsSet) {
     MIB.buildInstr(Mopcode, {DefDstPtr, DefSize},
-                   {DstPtrCopy, SizeCopy, SrcValCopy});
+                   {DstPtrCopy, SizeCopy, SrcValCopy})
+        .setOperandDead(5); // implicit-def $nzcv
   } else {
     Register DefSrcPtr = MRI.createVirtualRegister(&SrcValRegClass);
     MIB.buildInstr(Mopcode, {DefDstPtr, DefSrcPtr, DefSize},
-                   {DstPtrCopy, SrcValCopy, SizeCopy});
+                   {DstPtrCopy, SrcValCopy, SizeCopy})
+        .setOperandDead(6); // implicit-def $nzcv
   }
 
   GI.eraseFromParent();
@@ -6854,6 +6856,7 @@ bool AArch64InstructionSelector::selectIntrinsicWithSideEffects(
     auto Memset = MIB.buildInstr(AArch64::MOPSMemorySetTaggingPseudo,
                                  {DstDef, SizeDef}, {DstUse, SizeUse, ValUse});
     Memset.cloneMemRefs(I);
+    Memset.setOperandDead(5); // implicit-def $nzcv
     constrainSelectedInstRegOperands(*Memset, TII, TRI, RBI);
     break;
   }
diff --git a/llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll b/llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll
new file mode 100644
index 0000000000000..e32bfce7bd368
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll
@@ -0,0 +1,72 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+mops,+mte -global-isel -O0 -stop-after=instruction-select -o - %s | FileCheck %s
+
+define void @copy(ptr %d, ptr %s, i64 %n) {
+  ; CHECK-LABEL: name: copy
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK-NEXT:   liveins: $x0, $x1, $x2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64all = COPY $x0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr64all = COPY $x1
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr64all = COPY $x2
+  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY]]
+  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gpr64common = COPY [[COPY1]]
+  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gpr64 = COPY [[COPY2]]
+  ; CHECK-NEXT:   [[MOPSMemoryCopyPseudo:%[0-9]+]]:gpr64common, [[MOPSMemoryCopyPseudo1:%[0-9]+]]:gpr64common, [[MOPSMemoryCopyPseudo2:%[0-9]+]]:gpr64 = MOPSMemoryCopyPseudo [[COPY3]], [[COPY4]], [[COPY5]], implicit-def dead $nzcv
+  ; CHECK-NEXT:   RET_ReallyLR
+  call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %n, i1 false)
+  ret void
+}
+
+define void @move(ptr %d, ptr %s, i64 %n) {
+  ; CHECK-LABEL: name: move
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK-NEXT:   liveins: $x0, $x1, $x2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64all = COPY $x0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr64all = COPY $x1
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr64all = COPY $x2
+  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY]]
+  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gpr64common = COPY [[COPY1]]
+  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gpr64 = COPY [[COPY2]]
+  ; CHECK-NEXT:   [[MOPSMemoryMovePseudo:%[0-9]+]]:gpr64common, [[MOPSMemoryMovePseudo1:%[0-9]+]]:gpr64common, [[MOPSMemoryMovePseudo2:%[0-9]+]]:gpr64 = MOPSMemoryMovePseudo [[COPY3]], [[COPY4]], [[COPY5]], implicit-def dead $nzcv
+  ; CHECK-NEXT:   RET_ReallyLR
+  call void @llvm.memmove.p0.p0.i64(ptr %d, ptr %s, i64 %n, i1 false)
+  ret void
+}
+
+define void @set(ptr %d, i8 %v, i64 %n) {
+  ; CHECK-LABEL: name: set
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK-NEXT:   liveins: $w1, $x0, $x2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64all = COPY $x0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr64all = COPY $x2
+  ; CHECK-NEXT:   [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF
+  ; CHECK-NEXT:   [[INSERT_SUBREG:%[0-9]+]]:gpr64all = INSERT_SUBREG [[DEF]], [[COPY1]], %subreg.sub_32
+  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY]]
+  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gpr64 = COPY [[INSERT_SUBREG]]
+  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gpr64 = COPY [[COPY2]]
+  ; CHECK-NEXT:   %8:gpr64common, early-clobber %9:gpr64 = MOPSMemorySetPseudo [[COPY3]], [[COPY5]], [[COPY4]], implicit-def dead $nzcv
+  ; CHECK-NEXT:   RET_ReallyLR
+  call void @llvm.memset.p0.i64(ptr %d, i8 %v, i64 %n, i1 false)
+  ret void
+}
+
+define ptr @set_tag(ptr %d, i8 %v, i64 %n) {
+  ; CHECK-LABEL: name: set_tag
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK-NEXT:   liveins: $w1, $x0, $x2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64common = COPY $x0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr64 = COPY $x2
+  ; CHECK-NEXT:   [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF
+  ; CHECK-NEXT:   [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY1]], %subreg.sub_32
+  ; CHECK-NEXT:   [[MOPSMemorySetTaggingPseudo:%[0-9]+]]:gpr64common, [[MOPSMemorySetTaggingPseudo1:%[0-9]+]]:gpr64 = MOPSMemorySetTaggingPseudo [[COPY]], [[COPY2]], [[INSERT_SUBREG]], implicit-def dead $nzcv :: (store (i8) into %ir.d)
+  ; CHECK-NEXT:   $x0 = COPY [[MOPSMemorySetTaggingPseudo]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $x0
+  %r = call ptr @llvm.aarch64.mops.memset.tag(ptr %d, i8 %v, i64 %n)
+  ret ptr %r
+}

>From 4509a57fb0f889e1a159f60d42ea847ef9cb71dd Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 30 Sep 2026 12:18:28 +0200
Subject: [PATCH 2/2] Remove test

---
 llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll | 72 ---------------------
 1 file changed, 72 deletions(-)
 delete mode 100644 llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll

diff --git a/llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll b/llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll
deleted file mode 100644
index e32bfce7bd368..0000000000000
--- a/llvm/test/CodeGen/AArch64/mops-dead-nzcv.ll
+++ /dev/null
@@ -1,72 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
-; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+mops,+mte -global-isel -O0 -stop-after=instruction-select -o - %s | FileCheck %s
-
-define void @copy(ptr %d, ptr %s, i64 %n) {
-  ; CHECK-LABEL: name: copy
-  ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK-NEXT:   liveins: $x0, $x1, $x2
-  ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64all = COPY $x0
-  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr64all = COPY $x1
-  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr64all = COPY $x2
-  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY]]
-  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gpr64common = COPY [[COPY1]]
-  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gpr64 = COPY [[COPY2]]
-  ; CHECK-NEXT:   [[MOPSMemoryCopyPseudo:%[0-9]+]]:gpr64common, [[MOPSMemoryCopyPseudo1:%[0-9]+]]:gpr64common, [[MOPSMemoryCopyPseudo2:%[0-9]+]]:gpr64 = MOPSMemoryCopyPseudo [[COPY3]], [[COPY4]], [[COPY5]], implicit-def dead $nzcv
-  ; CHECK-NEXT:   RET_ReallyLR
-  call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %n, i1 false)
-  ret void
-}
-
-define void @move(ptr %d, ptr %s, i64 %n) {
-  ; CHECK-LABEL: name: move
-  ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK-NEXT:   liveins: $x0, $x1, $x2
-  ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64all = COPY $x0
-  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr64all = COPY $x1
-  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr64all = COPY $x2
-  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY]]
-  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gpr64common = COPY [[COPY1]]
-  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gpr64 = COPY [[COPY2]]
-  ; CHECK-NEXT:   [[MOPSMemoryMovePseudo:%[0-9]+]]:gpr64common, [[MOPSMemoryMovePseudo1:%[0-9]+]]:gpr64common, [[MOPSMemoryMovePseudo2:%[0-9]+]]:gpr64 = MOPSMemoryMovePseudo [[COPY3]], [[COPY4]], [[COPY5]], implicit-def dead $nzcv
-  ; CHECK-NEXT:   RET_ReallyLR
-  call void @llvm.memmove.p0.p0.i64(ptr %d, ptr %s, i64 %n, i1 false)
-  ret void
-}
-
-define void @set(ptr %d, i8 %v, i64 %n) {
-  ; CHECK-LABEL: name: set
-  ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK-NEXT:   liveins: $w1, $x0, $x2
-  ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64all = COPY $x0
-  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
-  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr64all = COPY $x2
-  ; CHECK-NEXT:   [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF
-  ; CHECK-NEXT:   [[INSERT_SUBREG:%[0-9]+]]:gpr64all = INSERT_SUBREG [[DEF]], [[COPY1]], %subreg.sub_32
-  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY]]
-  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gpr64 = COPY [[INSERT_SUBREG]]
-  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gpr64 = COPY [[COPY2]]
-  ; CHECK-NEXT:   %8:gpr64common, early-clobber %9:gpr64 = MOPSMemorySetPseudo [[COPY3]], [[COPY5]], [[COPY4]], implicit-def dead $nzcv
-  ; CHECK-NEXT:   RET_ReallyLR
-  call void @llvm.memset.p0.i64(ptr %d, i8 %v, i64 %n, i1 false)
-  ret void
-}
-
-define ptr @set_tag(ptr %d, i8 %v, i64 %n) {
-  ; CHECK-LABEL: name: set_tag
-  ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK-NEXT:   liveins: $w1, $x0, $x2
-  ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64common = COPY $x0
-  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
-  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr64 = COPY $x2
-  ; CHECK-NEXT:   [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF
-  ; CHECK-NEXT:   [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY1]], %subreg.sub_32
-  ; CHECK-NEXT:   [[MOPSMemorySetTaggingPseudo:%[0-9]+]]:gpr64common, [[MOPSMemorySetTaggingPseudo1:%[0-9]+]]:gpr64 = MOPSMemorySetTaggingPseudo [[COPY]], [[COPY2]], [[INSERT_SUBREG]], implicit-def dead $nzcv :: (store (i8) into %ir.d)
-  ; CHECK-NEXT:   $x0 = COPY [[MOPSMemorySetTaggingPseudo]]
-  ; CHECK-NEXT:   RET_ReallyLR implicit $x0
-  %r = call ptr @llvm.aarch64.mops.memset.tag(ptr %d, i8 %v, i64 %n)
-  ret ptr %r
-}



More information about the llvm-commits mailing list