Skip to content

AMDGPU/GlobalISel: Select all constants in tablegen #100788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 2 additions & 95 deletions llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2503,98 +2503,6 @@ bool AMDGPUInstructionSelector::selectG_FPEXT(MachineInstr &I) const {
return false;
}

bool AMDGPUInstructionSelector::selectG_CONSTANT(MachineInstr &I) const {
if (selectImpl(I, *CoverageInfo))
return true;

// FIXME: Relying on manual selection for 64-bit case, and pointer typed
// constants.
MachineBasicBlock *BB = I.getParent();
MachineOperand &ImmOp = I.getOperand(1);
Register DstReg = I.getOperand(0).getReg();
LLT Ty = MRI->getType(DstReg);
unsigned Size = Ty.getSizeInBits();
assert((Size == 64 || Ty.isPointer()) &&
"patterns should have selected this");

bool IsFP = false;

// The AMDGPU backend only supports Imm operands and not CImm or FPImm.
if (ImmOp.isFPImm()) {
const APInt &Imm = ImmOp.getFPImm()->getValueAPF().bitcastToAPInt();
ImmOp.ChangeToImmediate(Imm.getZExtValue());
IsFP = true;
} else if (ImmOp.isCImm()) {
ImmOp.ChangeToImmediate(ImmOp.getCImm()->getSExtValue());
} else {
llvm_unreachable("Not supported by g_constants");
}

const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
const bool IsSgpr = DstRB->getID() == AMDGPU::SGPRRegBankID;

unsigned Opcode;
if (DstRB->getID() == AMDGPU::VCCRegBankID) {
Opcode = STI.isWave32() ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64;
} else if (Size == 64 &&
AMDGPU::isValid32BitLiteral(I.getOperand(1).getImm(), IsFP)) {
Opcode = IsSgpr ? AMDGPU::S_MOV_B64_IMM_PSEUDO : AMDGPU::V_MOV_B64_PSEUDO;
I.setDesc(TII.get(Opcode));
I.addImplicitDefUseOperands(*MF);
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
} else {
Opcode = IsSgpr ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;

// We should never produce s1 values on banks other than VCC. If the user of
// this already constrained the register, we may incorrectly think it's VCC
// if it wasn't originally.
if (Size == 1)
return false;
}

if (Size != 64) {
I.setDesc(TII.get(Opcode));
I.addImplicitDefUseOperands(*MF);
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}

const DebugLoc &DL = I.getDebugLoc();

APInt Imm(Size, I.getOperand(1).getImm());

MachineInstr *ResInst;
if (IsSgpr && TII.isInlineConstant(Imm)) {
ResInst = BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_MOV_B64), DstReg)
.addImm(I.getOperand(1).getImm());
} else {
const TargetRegisterClass *RC = IsSgpr ?
&AMDGPU::SReg_32RegClass : &AMDGPU::VGPR_32RegClass;
Register LoReg = MRI->createVirtualRegister(RC);
Register HiReg = MRI->createVirtualRegister(RC);

BuildMI(*BB, &I, DL, TII.get(Opcode), LoReg)
.addImm(Imm.trunc(32).getZExtValue());

BuildMI(*BB, &I, DL, TII.get(Opcode), HiReg)
.addImm(Imm.ashr(32).getZExtValue());

ResInst = BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)
.addReg(LoReg)
.addImm(AMDGPU::sub0)
.addReg(HiReg)
.addImm(AMDGPU::sub1);
}

// We can't call constrainSelectedInstRegOperands here, because it doesn't
// work for target independent opcodes
I.eraseFromParent();
const TargetRegisterClass *DstRC =
TRI.getConstrainedRegClassForOperand(ResInst->getOperand(0), *MRI);
if (!DstRC)
return true;
return RBI.constrainGenericRegister(DstReg, *DstRC, *MRI);
}

bool AMDGPUInstructionSelector::selectG_FNEG(MachineInstr &MI) const {
// Only manually handle the f64 SGPR case.
//
Expand Down Expand Up @@ -3521,9 +3429,6 @@ bool AMDGPUInstructionSelector::select(MachineInstr &I) {
case TargetOpcode::G_PTRTOINT:
case TargetOpcode::G_FREEZE:
return selectCOPY(I);
case TargetOpcode::G_CONSTANT:
case TargetOpcode::G_FCONSTANT:
return selectG_CONSTANT(I);
case TargetOpcode::G_FNEG:
if (selectImpl(I, *CoverageInfo))
return true;
Expand Down Expand Up @@ -3629,6 +3534,8 @@ bool AMDGPUInstructionSelector::select(MachineInstr &I) {
return selectStackRestore(I);
case AMDGPU::G_PHI:
return selectPHI(I);
case TargetOpcode::G_CONSTANT:
case TargetOpcode::G_FCONSTANT:
default:
return selectImpl(I, *CoverageInfo);
}
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ class AMDGPUInstructionSelector final : public InstructionSelector {
bool selectG_TRUNC(MachineInstr &I) const;
bool selectG_SZA_EXT(MachineInstr &I) const;
bool selectG_FPEXT(MachineInstr &I) const;
bool selectG_CONSTANT(MachineInstr &I) const;
bool selectG_FNEG(MachineInstr &I) const;
bool selectG_FABS(MachineInstr &I) const;
bool selectG_AND_OR_XOR(MachineInstr &I) const;
Expand Down
44 changes: 24 additions & 20 deletions llvm/lib/Target/AMDGPU/SIInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -2140,15 +2140,17 @@ def : GCNPat <

// FIXME: Remove VGPRImm. Should be inferrable from register bank.

def : GCNPat <
(VGPRImm<(i32 imm)>:$imm),
(V_MOV_B32_e32 imm:$imm)
>;
foreach vt = [i32, p3, p5, p6, p2] in {
def : GCNPat <
(VGPRImm<(vt imm)>:$imm),
(V_MOV_B32_e32 imm:$imm)
>;

def : GCNPat <
(i32 imm:$imm),
(S_MOV_B32 imm:$imm)
>;
def : GCNPat <
(vt imm:$imm),
(S_MOV_B32 imm:$imm)
>;
}

def : GCNPat <
(p5 frameindex:$fi),
Expand Down Expand Up @@ -2257,20 +2259,22 @@ def : GCNPat <
(S_MOV_B32 (f32 (bitcast_fpimm_to_i32 $imm)))
>;

def : GCNPat <
(VGPRImm<(i64 imm)>:$imm),
(V_MOV_B64_PSEUDO imm:$imm)
>;
foreach vt = [i64, p1, p0, p4] in { // FIXME: Should accept arbitrary addrspace
def : GCNPat <
(VGPRImm<(vt imm)>:$imm),
(V_MOV_B64_PSEUDO imm:$imm)
>;

def : GCNPat <
(i64 InlineImm64:$imm),
(S_MOV_B64 InlineImm64:$imm)
>;
def : GCNPat <
(vt InlineImm64:$imm),
(S_MOV_B64 InlineImm64:$imm)
>;

def : GCNPat <
(i64 imm:$imm),
(S_MOV_B64_IMM_PSEUDO imm:$imm)
>;
def : GCNPat <
(vt imm:$imm),
(S_MOV_B64_IMM_PSEUDO imm:$imm)
>;
}

def : GCNPat <
(VGPRImm<(f64 fpimm)>:$imm),
Expand Down
Loading
Loading