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) <noreply@<!-- -->anthropic.com> --- 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
