llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

Previously we would only try to perform constant folding and simplifications
when an immediate was folded into an instruction, not if the input was already
a folded constant.

Co-authored-by: Claude (Opus 4.8) &lt;noreply@<!-- -->anthropic.com&gt;

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


3 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/SIFoldOperands.cpp (+9-18) 
- (modified) llvm/test/CodeGen/AMDGPU/promote-constOffset-to-imm-gfx12.mir (-4) 
- (added) 
llvm/test/CodeGen/AMDGPU/si-fold-operands-constant-fold-imm-operand.mir (+115) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp 
b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
index 3fdbb74eb3342..5a6f0e710ae0f 100644
--- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
@@ -1806,24 +1806,6 @@ bool SIFoldOperandsImpl::foldInstOperand(MachineInstr 
&MI,
   MachineOperand &Dst = MI.getOperand(0);
   bool Changed = false;
 
-  if (OpToFold.isImm()) {
-    for (auto &UseMI :
-         make_early_inc_range(MRI->use_nodbg_instructions(Dst.getReg()))) {
-      // Folding the immediate may reveal operations that can be constant
-      // folded or replaced with a copy. This can happen for example after
-      // frame indices are lowered to constants or from splitting 64-bit
-      // constants.
-      //
-      // We may also encounter cases where one or both operands are
-      // immediates materialized into a register, which would ordinarily not
-      // be folded due to multiple uses or operand constraints.
-      if (tryConstantFoldOp(&UseMI)) {
-        LLVM_DEBUG(dbgs() << "Constant folded " << UseMI);
-        Changed = true;
-      }
-    }
-  }
-
   SmallVector<MachineOperand *, 4> UsesToProcess(
       llvm::make_pointer_range(MRI->use_nodbg_operands(Dst.getReg())));
   for (auto *U : UsesToProcess) {
@@ -2832,6 +2814,15 @@ bool SIFoldOperandsImpl::run(MachineFunction &MF) {
     for (auto &MI : make_early_inc_range(*MBB)) {
       Changed |= tryFoldCndMask(MI);
 
+      // PeepholeOptimizer may have folded an inline immediate directly onto an
+      // instruction operand without materializing it into a register first.
+      // Such an instruction is never reached through a def->use edge in
+      // foldInstOperand, so try to constant fold it here.
+      if (tryConstantFoldOp(&MI)) {
+        Changed = true;
+        continue;
+      }
+
       if (tryFoldZeroHighBits(MI)) {
         Changed = true;
         continue;
diff --git a/llvm/test/CodeGen/AMDGPU/promote-constOffset-to-imm-gfx12.mir 
b/llvm/test/CodeGen/AMDGPU/promote-constOffset-to-imm-gfx12.mir
index 5c043eadf6096..f232c3da15c18 100644
--- a/llvm/test/CodeGen/AMDGPU/promote-constOffset-to-imm-gfx12.mir
+++ b/llvm/test/CodeGen/AMDGPU/promote-constOffset-to-imm-gfx12.mir
@@ -22,7 +22,6 @@ body:             |
     ; GFX1250-NEXT: renamable $vgpr1 = V_LSHLREV_B32_e32 8, $vgpr0, implicit 
$exec
     ; GFX1250-NEXT: renamable $vgpr2, renamable $vcc_lo = V_ADD_CO_U32_e64 
256, $vgpr0, 0, implicit $exec
     ; GFX1250-NEXT: renamable $vgpr3, $sgpr_null = V_ADDC_U32_e64 0, killed 
$vgpr0, killed $vcc_lo, 0, implicit $exec
-    ; GFX1250-NEXT: renamable $vgpr1 = disjoint V_OR_B32_e32 0, killed $vgpr1, 
implicit $exec
     ; GFX1250-NEXT: renamable $vgpr0 = V_ADD_U32_e32 -256, $vgpr1, implicit 
$exec
     ; GFX1250-NEXT: GLOBAL_LOAD_ASYNC_TO_LDS_B128 killed $vgpr1, $vgpr2_vgpr3, 
0, 0, implicit-def $asynccnt, implicit $exec, implicit $asynccnt :: (load store 
(s128), align 1, addrspace 3)
     ; GFX1250-NEXT: GLOBAL_LOAD_ASYNC_TO_LDS_B128 killed $vgpr0, killed 
$vgpr2_vgpr3, 256, 0, implicit-def $asynccnt, implicit $exec, implicit 
$asynccnt :: (load store (s128), align 1, addrspace 3)
@@ -62,7 +61,6 @@ body:             |
     ; GFX1250-NEXT: renamable $vgpr1 = V_LSHLREV_B32_e32 8, $vgpr0, implicit 
$exec
     ; GFX1250-NEXT: renamable $vgpr2, renamable $vcc_lo = V_ADD_CO_U32_e64 
256, $vgpr0, 0, implicit $exec
     ; GFX1250-NEXT: renamable $vgpr3, $sgpr_null = V_ADDC_U32_e64 0, killed 
$vgpr0, killed $vcc_lo, 0, implicit $exec
-    ; GFX1250-NEXT: renamable $vgpr1 = disjoint V_OR_B32_e32 0, killed $vgpr1, 
implicit $exec
     ; GFX1250-NEXT: renamable $vgpr0 = V_ADD_U32_e32 -256, $vgpr1, implicit 
$exec
     ; GFX1250-NEXT: renamable $vgpr4 = V_ADD_U32_e32 -260, $vgpr1, implicit 
$exec
     ; GFX1250-NEXT: GLOBAL_LOAD_ASYNC_TO_LDS_B128 killed $vgpr1, $vgpr2_vgpr3, 
0, 0, implicit-def $asynccnt, implicit $exec, implicit $asynccnt :: (load store 
(s128), align 1, addrspace 3)
@@ -157,7 +155,6 @@ body:             |
     ; GFX1250-NEXT: renamable $vgpr1 = V_LSHLREV_B32_e32 8, $vgpr0, implicit 
$exec
     ; GFX1250-NEXT: renamable $vgpr2, renamable $vcc_lo = V_ADD_CO_U32_e64 
256, $vgpr0, 0, implicit $exec
     ; GFX1250-NEXT: renamable $vgpr3, $sgpr_null = V_ADDC_U32_e64 0, killed 
$vgpr0, killed $vcc_lo, 0, implicit $exec
-    ; GFX1250-NEXT: renamable $vgpr1 = disjoint V_OR_B32_e32 0, killed $vgpr1, 
implicit $exec
     ; GFX1250-NEXT: renamable $vgpr0 = V_ADD_U32_e32 -256, $vgpr1, implicit 
$exec
     ; GFX1250-NEXT: renamable $vgpr4 = V_ADD_U32_e32 -512, $vgpr1, implicit 
$exec
     ; GFX1250-NEXT: GLOBAL_LOAD_ASYNC_TO_LDS_B128 killed $vgpr1, $vgpr2_vgpr3, 
0, 0, implicit-def $asynccnt, implicit $exec, implicit $asynccnt :: (load store 
(s128), align 1, addrspace 3)
@@ -206,7 +203,6 @@ body:             |
     ; GFX1250-NEXT: renamable $vgpr1 = V_LSHLREV_B32_e32 8, $vgpr0, implicit 
$exec
     ; GFX1250-NEXT: renamable $vgpr2, renamable $vcc_lo = V_ADD_CO_U32_e64 
256, $vgpr0, 0, implicit $exec
     ; GFX1250-NEXT: renamable $vgpr3, $sgpr_null = V_ADDC_U32_e64 0, killed 
$vgpr0, killed $vcc_lo, 0, implicit $exec
-    ; GFX1250-NEXT: renamable $vgpr1 = disjoint V_OR_B32_e32 0, killed $vgpr1, 
implicit $exec
     ; GFX1250-NEXT: renamable $vgpr0 = V_ADD_U32_e32 -256, $vgpr1, implicit 
$exec
     ; GFX1250-NEXT: GLOBAL_STORE_ASYNC_FROM_LDS_B128 $vgpr2_vgpr3, killed 
$vgpr1, 0, 0, implicit-def $asynccnt, implicit $exec, implicit $asynccnt :: 
(load store (s128), align 1, addrspace 3)
     ; GFX1250-NEXT: GLOBAL_STORE_ASYNC_FROM_LDS_B128 killed $vgpr2_vgpr3, 
killed $vgpr0, 256, 0, implicit-def $asynccnt, implicit $exec, implicit 
$asynccnt :: (load store (s128), align 1, addrspace 3)
diff --git 
a/llvm/test/CodeGen/AMDGPU/si-fold-operands-constant-fold-imm-operand.mir 
b/llvm/test/CodeGen/AMDGPU/si-fold-operands-constant-fold-imm-operand.mir
new file mode 100644
index 0000000000000..9206ffb149ca0
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/si-fold-operands-constant-fold-imm-operand.mir
@@ -0,0 +1,115 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 
UTC_ARGS: --version 6
+# RUN: llc -mtriple=amdgcn -mcpu=gfx900 -run-pass=si-fold-operands -o - %s | 
FileCheck %s
+
+# Check that si-fold-operands will perform simplifications and
+# constant folding of instructions that already have immediate
+# operands.
+
+---
+name:            v_and_imm_zero_operand_to_mov
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $vgpr0
+
+    ; CHECK-LABEL: name: v_and_imm_zero_operand_to_mov
+    ; CHECK: liveins: $vgpr0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
+    ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, 
implicit $exec
+    ; CHECK-NEXT: SI_RETURN_TO_EPILOG [[V_MOV_B32_e32_]]
+    %0:vgpr_32 = COPY $vgpr0
+    %1:vgpr_32 = V_AND_B32_e32 0, %0, implicit $exec
+    SI_RETURN_TO_EPILOG %1
+
+...
+
+---
+name:            v_and_imm_neg1_operand_to_copy
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $vgpr0
+
+    ; CHECK-LABEL: name: v_and_imm_neg1_operand_to_copy
+    ; CHECK: liveins: $vgpr0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[COPY]]
+    ; CHECK-NEXT: SI_RETURN_TO_EPILOG [[COPY1]]
+    %0:vgpr_32 = COPY $vgpr0
+    %1:vgpr_32 = V_AND_B32_e32 -1, %0, implicit $exec
+    SI_RETURN_TO_EPILOG %1
+
+...
+
+---
+name:            v_or_imm_neg1_operand_to_mov
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $vgpr0
+
+    ; CHECK-LABEL: name: v_or_imm_neg1_operand_to_mov
+    ; CHECK: liveins: $vgpr0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
+    ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 -1, 
implicit $exec
+    ; CHECK-NEXT: SI_RETURN_TO_EPILOG [[V_MOV_B32_e32_]]
+    %0:vgpr_32 = COPY $vgpr0
+    %1:vgpr_32 = V_OR_B32_e32 -1, %0, implicit $exec
+    SI_RETURN_TO_EPILOG %1
+
+...
+
+---
+name:            v_xor_imm_zero_operand_to_copy
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $vgpr0
+
+    ; CHECK-LABEL: name: v_xor_imm_zero_operand_to_copy
+    ; CHECK: liveins: $vgpr0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[COPY]]
+    ; CHECK-NEXT: SI_RETURN_TO_EPILOG [[COPY1]]
+    %0:vgpr_32 = COPY $vgpr0
+    %1:vgpr_32 = V_XOR_B32_e32 0, %0, implicit $exec
+    SI_RETURN_TO_EPILOG %1
+
+...
+
+---
+name:            s_add_imm_zero_operand_to_copy
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $sgpr0
+
+    ; CHECK-LABEL: name: s_add_imm_zero_operand_to_copy
+    ; CHECK: liveins: $sgpr0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY [[COPY]]
+    ; CHECK-NEXT: SI_RETURN_TO_EPILOG [[COPY1]]
+    %0:sreg_32 = COPY $sgpr0
+    %1:sreg_32 = S_ADD_U32 %0, 0, implicit-def dead $scc
+    SI_RETURN_TO_EPILOG %1
+
+...
+
+---
+name:            s_not_imm_operand_to_mov
+tracksRegLiveness: true
+body:             |
+  bb.0:
+
+    ; CHECK-LABEL: name: s_not_imm_operand_to_mov
+    ; CHECK: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 -2
+    ; CHECK-NEXT: SI_RETURN_TO_EPILOG [[S_MOV_B32_]]
+    %0:sreg_32 = S_NOT_B32 1, implicit-def dead $scc
+    SI_RETURN_TO_EPILOG %0
+
+...

``````````

</details>


https://github.com/llvm/llvm-project/pull/208422
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to