Skip to content

Commit 83d7f4b

Browse files
authored
AMDGPU: Implement getConstValDefinedInReg and use in foldImmediate (NFC) (#127482)
This is NFC because it currently only matters for cases that are not isMoveImmediate, and we do not yet implement any of those. This just moves the implementation of foldImmediate to use the common interface, similar to how x86 does it.
1 parent af1e2a3 commit 83d7f4b

File tree

2 files changed

+54
-35
lines changed

2 files changed

+54
-35
lines changed

llvm/lib/Target/AMDGPU/SIInstrInfo.cpp

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
13301357
unsigned 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:

llvm/lib/Target/AMDGPU/SIInstrInfo.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,9 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
278278
MachineBasicBlock::iterator I, const DebugLoc &DL,
279279
Register SrcReg, int Value) const;
280280

281+
bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg,
282+
int64_t &ImmVal) const override;
283+
281284
void storeRegToStackSlot(
282285
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,
283286
bool isKill, int FrameIndex, const TargetRegisterClass *RC,
@@ -1063,7 +1066,13 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
10631066
// Some operands like FrameIndexes could resolve to an inline immediate value
10641067
// that will not require an additional 4-bytes; this function assumes that it
10651068
// will.
1066-
bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
1069+
bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const {
1070+
assert(!MO.isReg() && "isInlineConstant called on register operand!");
1071+
if (!MO.isImm())
1072+
return false;
1073+
return isInlineConstant(MO.getImm(), OperandType);
1074+
}
1075+
bool isInlineConstant(int64_t ImmVal, uint8_t OperandType) const;
10671076

10681077
bool isInlineConstant(const MachineOperand &MO,
10691078
const MCOperandInfo &OpInfo) const {
@@ -1091,7 +1100,7 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
10911100
}
10921101

10931102
bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
1094-
const MachineOperand &MO) const {
1103+
int64_t ImmVal) const {
10951104
if (OpIdx >= MI.getDesc().NumOperands)
10961105
return false;
10971106

@@ -1101,10 +1110,15 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
11011110

11021111
uint8_t OpType = (Size == 8) ?
11031112
AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
1104-
return isInlineConstant(MO, OpType);
1113+
return isInlineConstant(ImmVal, OpType);
11051114
}
11061115

1107-
return isInlineConstant(MO, MI.getDesc().operands()[OpIdx].OperandType);
1116+
return isInlineConstant(ImmVal, MI.getDesc().operands()[OpIdx].OperandType);
1117+
}
1118+
1119+
bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
1120+
const MachineOperand &MO) const {
1121+
return isInlineConstant(MI, OpIdx, MO.getImm());
11081122
}
11091123

11101124
bool isInlineConstant(const MachineOperand &MO) const {

0 commit comments

Comments
 (0)