GlobalISel: Handle llvm.read_register

Compared to the attempt in bdcc6d3d26,
this uses intermediate generic instructions.
This commit is contained in:
Matt Arsenault 2019-12-27 19:26:51 -05:00 committed by Matt Arsenault
parent f33f3d98e9
commit 0ea3c7291f
7 changed files with 59 additions and 2 deletions

View File

@ -240,6 +240,7 @@ public:
LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
LegalizeResult lowerBswap(MachineInstr &MI);
LegalizeResult lowerBitreverse(MachineInstr &MI);
LegalizeResult lowerReadRegister(MachineInstr &MI);
private:
MachineRegisterInfo &MRI;

View File

@ -614,12 +614,16 @@ HANDLE_TARGET_OPCODE(G_JUMP_TABLE)
/// Generic dynamic stack allocation.
HANDLE_TARGET_OPCODE(G_DYN_STACKALLOC)
// TODO: Add more generic opcodes as we move along.
/// read_register intrinsic
HANDLE_TARGET_OPCODE(G_READ_REGISTER)
/// write_register intrinsic
HANDLE_TARGET_OPCODE(G_WRITE_REGISTER)
/// Marker for the end of the generic opcode.
/// This is used to check if an opcode is in the range of the
/// generic opcodes.
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_DYN_STACKALLOC)
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_WRITE_REGISTER)
/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific post-isel opcode values start here.

View File

@ -1012,6 +1012,26 @@ def G_BRJT : GenericInstruction {
let isTerminator = 1;
}
def G_READ_REGISTER : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$register);
let hasSideEffects = 1;
// Assume convergent. It's probably not worth the effort of somehow
// modeling convergent and nonconvergent register accesses.
let isConvergent = 1;
}
def G_WRITE_REGISTER : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins unknown:$register, type0:$value);
let hasSideEffects = 1;
// Assume convergent. It's probably not worth the effort of somehow
// modeling convergent and nonconvergent register accesses.
let isConvergent = 1;
}
//------------------------------------------------------------------------------
// Vector ops
//------------------------------------------------------------------------------

View File

@ -1526,6 +1526,13 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
case Intrinsic::sideeffect:
// Discard annotate attributes, assumptions, and artificial side-effects.
return true;
case Intrinsic::read_register: {
Value *Arg = CI.getArgOperand(0);
MIRBuilder.buildInstr(TargetOpcode::G_READ_REGISTER)
.addDef(getOrCreateVReg(CI))
.addMetadata(cast<MDNode>(cast<MetadataAsValue>(Arg)->getMetadata()));
return true;
}
}
return false;
}

View File

@ -2317,6 +2317,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
return lowerBswap(MI);
case G_BITREVERSE:
return lowerBitreverse(MI);
case G_READ_REGISTER:
return lowerReadRegister(MI);
}
}
@ -4469,3 +4471,22 @@ LegalizerHelper::lowerBitreverse(MachineInstr &MI) {
MI.eraseFromParent();
return Legalized;
}
LegalizerHelper::LegalizeResult
LegalizerHelper::lowerReadRegister(MachineInstr &MI) {
Register Dst = MI.getOperand(0).getReg();
const LLT Ty = MRI.getType(Dst);
const MDString *RegStr = cast<MDString>(
cast<MDNode>(MI.getOperand(1).getMetadata())->getOperand(0));
MachineFunction &MF = MIRBuilder.getMF();
const TargetSubtargetInfo &STI = MF.getSubtarget();
const TargetLowering *TLI = STI.getTargetLowering();
Register Reg = TLI->getRegisterByName(RegStr->getString().data(), Ty, MF);
if (!Reg.isValid())
return UnableToLegalize;
MIRBuilder.buildCopy(Dst, Reg);
MI.eraseFromParent();
return Legalized;
}

View File

@ -1116,6 +1116,8 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
getActionDefinitionsBuilder(G_SEXT_INREG).lower();
getActionDefinitionsBuilder({G_READ_REGISTER, G_WRITE_REGISTER}).lower();
getActionDefinitionsBuilder(G_READCYCLECOUNTER)
.legalFor({S64});

View File

@ -0,0 +1,2 @@
; Runs original SDAG test with -global-isel
; RUN: llc -global-isel -mtriple=amdgcn-amd-amdhsa -mcpu=bonaire -verify-machineinstrs < %S/../read_register.ll | FileCheck -enable-var-scope %S/../read_register.ll