[llvm] [AMDGPU] SIInstrInfo: Fix resultDependsOnExec for VOPC instructions (PR #134629)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 7 06:40:27 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Frederik Harwath (frederik-h)

<details>
<summary>Changes</summary>

SIInstrInfo::resultDependsOnExec assumes that operand 0 of a comparison is always the destination of the instruction. This is not true for instructions in VOPC form where it is "src0". This led to a crash in machine-cse.

Additional unrelated change: Fix spelling mistakes in doc comment.

---
Full diff: https://github.com/llvm/llvm-project/pull/134629.diff


3 Files Affected:

- (modified) llvm/lib/CodeGen/MachineCSE.cpp (+4-4) 
- (modified) llvm/lib/Target/AMDGPU/SIInstrInfo.cpp (+3) 
- (added) llvm/test/CodeGen/AMDGPU/si-instr-info-vopc-no-exec.mir (+23) 


``````````diff
diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp
index 6d14509c5934f..1ebf7b96a3b94 100644
--- a/llvm/lib/CodeGen/MachineCSE.cpp
+++ b/llvm/lib/CodeGen/MachineCSE.cpp
@@ -278,10 +278,10 @@ static bool isCallerPreservedOrConstPhysReg(MCRegister Reg,
          (MRI.reservedRegsFrozen() && MRI.isConstantPhysReg(Reg));
 }
 
-/// hasLivePhysRegDefUses - Return true if the specified instruction read/write
-/// physical registers (except for dead defs of physical registers). It also
-/// returns the physical register def by reference if it's the only one and the
-/// instruction does not uses a physical register.
+/// hasLivePhysRegDefUses - Return true if the specified instruction
+/// reads/writes physical registers (except for dead defs of physical
+/// registers). It also returns the physical register def by reference if it's
+/// the only one and the instruction does not use a physical register.
 bool MachineCSEImpl::hasLivePhysRegDefUses(const MachineInstr *MI,
                                            const MachineBasicBlock *MBB,
                                            SmallSet<MCRegister, 8> &PhysRefs,
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index 61fda0eef6314..4990c9a74f6ee 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -151,6 +151,9 @@ static bool resultDependsOnExec(const MachineInstr &MI) {
   // Ignore comparisons which are only used masked with exec.
   // This allows some hoisting/sinking of VALU comparisons.
   if (MI.isCompare()) {
+    if (SIInstrInfo::isVOPC(MI))
+      return false;
+
     const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
     Register DstReg = MI.getOperand(0).getReg();
     if (!DstReg.isVirtual())
diff --git a/llvm/test/CodeGen/AMDGPU/si-instr-info-vopc-no-exec.mir b/llvm/test/CodeGen/AMDGPU/si-instr-info-vopc-no-exec.mir
new file mode 100644
index 0000000000000..f1e9447dbd349
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/si-instr-info-vopc-no-exec.mir
@@ -0,0 +1,23 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1010 -run-pass=machine-cse %s -o - | FileCheck %s
+
+---
+name: vopc_comparisons_do_not_depend_on_exec
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: vopc_comparisons_do_not_depend_on_exec
+    ; CHECK: [[DEF:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
+    ; CHECK-NEXT: V_CMP_EQ_U32_e32 1, killed undef [[DEF]], implicit-def $vcc_lo, implicit $exec
+    ; CHECK-NEXT: [[V_CNDMASK_B32_e32_:%[0-9]+]]:vgpr_32 = V_CNDMASK_B32_e32 16256, undef [[DEF]], implicit $vcc_lo, implicit $exec
+    ; CHECK-NEXT: [[V_LSHLREV_B32_e64_:%[0-9]+]]:vgpr_32 = V_LSHLREV_B32_e64 16, undef [[V_CNDMASK_B32_e32_]], implicit $exec
+    ; CHECK-NEXT: SI_RETURN
+    %0:vgpr_32 = IMPLICIT_DEF
+    V_CMP_EQ_U32_e32 1, killed undef %0, implicit-def $vcc, implicit $exec
+    %1:vgpr_32 = V_CNDMASK_B32_e32 16256, undef %0, implicit $vcc, implicit $exec
+    V_CMP_EQ_U32_e32 1, killed undef %0, implicit-def $vcc, implicit $exec
+    %2:vgpr_32 = V_CNDMASK_B32_e32 16256, undef %0, implicit $vcc, implicit $exec
+    %3:vgpr_32 = V_LSHLREV_B32_e64 16, killed undef %2, implicit $exec
+    %4:vgpr_32 = V_LSHLREV_B32_e64 16, killed undef %1, implicit $exec
+    SI_RETURN
+...

``````````

</details>


https://github.com/llvm/llvm-project/pull/134629


More information about the llvm-commits mailing list