[llvm] AMDGPU: Replace copy-to-mov-imm folding logic with class compat checks (PR #154501)
Pierre van Houtryve via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 26 02:30:22 PDT 2025
================
@@ -1278,44 +1279,60 @@ void SIFoldOperandsImpl::foldOperand(
DestRC = &AMDGPU::SGPR_32RegClass;
}
- // In order to fold immediates into copies, we need to change the
- // copy to a MOV.
+ // In order to fold immediates into copies, we need to change the copy to a
+ // MOV. Find a compatible mov instruction with the value.
+ for (unsigned MovOp :
+ {AMDGPU::S_MOV_B32, AMDGPU::V_MOV_B32_e32, AMDGPU::S_MOV_B64,
+ AMDGPU::V_MOV_B64_PSEUDO, AMDGPU::V_MOV_B16_t16_e64}) {
+ const MCInstrDesc &MovDesc = TII->get(MovOp);
+ assert(MovDesc.getNumDefs() > 0 && MovDesc.operands()[0].RegClass != -1);
+
+ const TargetRegisterClass *MovDstRC =
+ TRI->getRegClass(MovDesc.operands()[0].RegClass);
+
+ // Fold if the destination register class of the MOV instruction (ResRC)
+ // is a superclass of (or equal to) the destination register class of the
+ // COPY (DestRC). If this condition fails, folding would be illegal.
+ if (!DestRC->hasSuperClassEq(MovDstRC))
+ continue;
- unsigned MovOp = TII->getMovOpcode(DestRC);
- if (MovOp == AMDGPU::COPY)
- return;
+ const int SrcIdx = MovOp == AMDGPU::V_MOV_B16_t16_e64 ? 2 : 1;
+ const TargetRegisterClass *MovSrcRC =
+ TRI->getRegClass(MovDesc.operands()[SrcIdx].RegClass);
- // Fold if the destination register class of the MOV instruction (ResRC)
- // is a superclass of (or equal to) the destination register class of the
- // COPY (DestRC). If this condition fails, folding would be illegal.
- const MCInstrDesc &MovDesc = TII->get(MovOp);
- assert(MovDesc.getNumDefs() > 0 && MovDesc.operands()[0].RegClass != -1);
- const TargetRegisterClass *ResRC =
- TRI->getRegClass(MovDesc.operands()[0].RegClass);
- if (!DestRC->hasSuperClassEq(ResRC))
- return;
+ if (UseSubReg)
+ MovSrcRC = TRI->getMatchingSuperRegClass(SrcRC, MovSrcRC, UseSubReg);
+ if (!MRI->constrainRegClass(SrcReg, MovSrcRC))
+ break;
- MachineInstr::mop_iterator ImpOpI = UseMI->implicit_operands().begin();
- MachineInstr::mop_iterator ImpOpE = UseMI->implicit_operands().end();
- while (ImpOpI != ImpOpE) {
- MachineInstr::mop_iterator Tmp = ImpOpI;
- ImpOpI++;
- UseMI->removeOperand(UseMI->getOperandNo(Tmp));
- }
- UseMI->setDesc(TII->get(MovOp));
-
- if (MovOp == AMDGPU::V_MOV_B16_t16_e64) {
- const auto &SrcOp = UseMI->getOperand(UseOpIdx);
- MachineOperand NewSrcOp(SrcOp);
- MachineFunction *MF = UseMI->getParent()->getParent();
- UseMI->removeOperand(1);
- UseMI->addOperand(*MF, MachineOperand::CreateImm(0)); // src0_modifiers
- UseMI->addOperand(NewSrcOp); // src0
- UseMI->addOperand(*MF, MachineOperand::CreateImm(0)); // op_sel
- UseOpIdx = 2;
- UseOp = &UseMI->getOperand(UseOpIdx);
+ MachineInstr::mop_iterator ImpOpI = UseMI->implicit_operands().begin();
+ MachineInstr::mop_iterator ImpOpE = UseMI->implicit_operands().end();
+ while (ImpOpI != ImpOpE) {
+ MachineInstr::mop_iterator Tmp = ImpOpI;
+ ImpOpI++;
+ UseMI->removeOperand(UseMI->getOperandNo(Tmp));
+ }
----------------
Pierre-vh wrote:
Don't we have helpers to remove all implicit operands? It feels like we should have one
Maybe put this in a small static helper ?
https://github.com/llvm/llvm-project/pull/154501
More information about the llvm-commits
mailing list