@@ -1327,6 +1327,33 @@ Register SIInstrInfo::insertNE(MachineBasicBlock *MBB,
13271327 return Reg;
13281328}
13291329
1330+ bool SIInstrInfo::getConstValDefinedInReg (const MachineInstr &MI,
1331+ const Register Reg,
1332+ int64_t &ImmVal) const {
1333+ // TODO: Handle all the special cases handled in SIShrinkInstructions
1334+ // (e.g. s_brev_b32 imm -> reverse(imm))
1335+ switch (MI.getOpcode ()) {
1336+ case AMDGPU::V_MOV_B32_e32:
1337+ case AMDGPU::S_MOV_B32:
1338+ case AMDGPU::S_MOVK_I32:
1339+ case AMDGPU::S_MOV_B64:
1340+ case AMDGPU::V_MOV_B64_e32:
1341+ case AMDGPU::V_ACCVGPR_WRITE_B32_e64:
1342+ case AMDGPU::S_MOV_B64_IMM_PSEUDO:
1343+ case AMDGPU::V_MOV_B64_PSEUDO: {
1344+ const MachineOperand &Src0 = MI.getOperand (1 );
1345+ if (Src0.isImm ()) {
1346+ ImmVal = Src0.getImm ();
1347+ return MI.getOperand (0 ).getReg () == Reg;
1348+ }
1349+
1350+ return false ;
1351+ }
1352+ default :
1353+ return false ;
1354+ }
1355+ }
1356+
13301357unsigned SIInstrInfo::getMovOpcode (const TargetRegisterClass *DstRC) const {
13311358
13321359 if (RI.isAGPRClass (DstRC))
@@ -3395,27 +3422,11 @@ bool SIInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
33953422 if (!MRI->hasOneNonDBGUse (Reg))
33963423 return false ;
33973424
3398- switch (DefMI.getOpcode ()) {
3399- default :
3400- return false ;
3401- case AMDGPU::V_MOV_B64_e32:
3402- case AMDGPU::S_MOV_B64:
3403- case AMDGPU::V_MOV_B64_PSEUDO:
3404- case AMDGPU::S_MOV_B64_IMM_PSEUDO:
3405- case AMDGPU::V_MOV_B32_e32:
3406- case AMDGPU::S_MOV_B32:
3407- case AMDGPU::V_ACCVGPR_WRITE_B32_e64:
3408- break ;
3409- }
3410-
3411- const MachineOperand *ImmOp = getNamedOperand (DefMI, AMDGPU::OpName::src0);
3412- assert (ImmOp);
3413- // FIXME: We could handle FrameIndex values here.
3414- if (!ImmOp->isImm ())
3425+ int64_t Imm;
3426+ if (!getConstValDefinedInReg (DefMI, Reg, Imm))
34153427 return false ;
34163428
3417- auto getImmFor = [ImmOp](const MachineOperand &UseOp) -> int64_t {
3418- int64_t Imm = ImmOp->getImm ();
3429+ auto getImmFor = [=](const MachineOperand &UseOp) -> int64_t {
34193430 switch (UseOp.getSubReg ()) {
34203431 default :
34213432 return Imm;
@@ -3502,12 +3513,14 @@ bool SIInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
35023513 // If this is a free constant, there's no reason to do this.
35033514 // TODO: We could fold this here instead of letting SIFoldOperands do it
35043515 // later.
3505- MachineOperand *Src0 = getNamedOperand (UseMI, AMDGPU::OpName::src0);
3516+ int Src0Idx = getNamedOperandIdx (UseMI. getOpcode () , AMDGPU::OpName::src0);
35063517
35073518 // Any src operand can be used for the legality check.
3508- if (isInlineConstant (UseMI, *Src0, *ImmOp ))
3519+ if (isInlineConstant (UseMI, Src0Idx, Imm ))
35093520 return false ;
35103521
3522+ MachineOperand *Src0 = &UseMI.getOperand (Src0Idx);
3523+
35113524 bool IsF32 = Opc == AMDGPU::V_MAD_F32_e64 || Opc == AMDGPU::V_MAC_F32_e64 ||
35123525 Opc == AMDGPU::V_FMA_F32_e64 || Opc == AMDGPU::V_FMAC_F32_e64;
35133526 bool IsFMA =
@@ -4267,18 +4280,11 @@ bool SIInstrInfo::isInlineConstant(const APFloat &Imm) const {
42674280 }
42684281}
42694282
4270- bool SIInstrInfo::isInlineConstant (const MachineOperand &MO,
4271- uint8_t OperandType) const {
4272- assert (!MO.isReg () && " isInlineConstant called on register operand!" );
4273- if (!MO.isImm ())
4274- return false ;
4275-
4283+ bool SIInstrInfo::isInlineConstant (int64_t Imm, uint8_t OperandType) const {
42764284 // MachineOperand provides no way to tell the true operand size, since it only
42774285 // records a 64-bit value. We need to know the size to determine if a 32-bit
42784286 // floating point immediate bit pattern is legal for an integer immediate. It
42794287 // would be for any 32-bit integer operand, but would not be for a 64-bit one.
4280-
4281- int64_t Imm = MO.getImm ();
42824288 switch (OperandType) {
42834289 case AMDGPU::OPERAND_REG_IMM_INT32:
42844290 case AMDGPU::OPERAND_REG_IMM_FP32:
@@ -4300,8 +4306,7 @@ bool SIInstrInfo::isInlineConstant(const MachineOperand &MO,
43004306 case AMDGPU::OPERAND_REG_INLINE_C_INT64:
43014307 case AMDGPU::OPERAND_REG_INLINE_C_FP64:
43024308 case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
4303- return AMDGPU::isInlinableLiteral64 (MO.getImm (),
4304- ST.hasInv2PiInlineImm ());
4309+ return AMDGPU::isInlinableLiteral64 (Imm, ST.hasInv2PiInlineImm ());
43054310 case AMDGPU::OPERAND_REG_IMM_INT16:
43064311 case AMDGPU::OPERAND_REG_INLINE_C_INT16:
43074312 case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
0 commit comments