radeon/llvm: Use multiclasses for floating point loads

The original strategy for handling floating point loads, which was to
lower (f32 load) to (f32 bitcast (i32 load)) wasn't really working.  The
main problem was that the DAG legalizer couldn't handle replacing a node
with two results (load) with a node with only one result (bitcast).
This commit is contained in:
Tom Stellard 2012-07-10 11:15:49 -04:00
parent bbdf3af857
commit 49ae102ee3
7 changed files with 46 additions and 50 deletions

View file

@ -33,9 +33,6 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
setOperationAction(ISD::FEXP2, MVT::f32, Legal);
setOperationAction(ISD::FRINT, MVT::f32, Legal);
setOperationAction(ISD::LOAD, MVT::f32, Custom);
setOperationAction(ISD::LOAD, MVT::v4f32, Custom);
setOperationAction(ISD::UDIV, MVT::i32, Expand);
setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
setOperationAction(ISD::UREM, MVT::i32, Expand);
@ -47,7 +44,6 @@ SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
switch (Op.getOpcode()) {
default: return AMDILTargetLowering::LowerOperation(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
case ISD::LOAD: return BitcastLOAD(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
}
@ -130,36 +126,6 @@ SDValue AMDGPUTargetLowering::LowerIntrinsicLRP(SDValue Op,
OneSubAC);
}
/// BitcastLoad - Convert floating point loads to integer loads of the same
/// type width and the bitcast the result back to a floating point type.
SDValue AMDGPUTargetLowering::BitcastLOAD(SDValue Op, SelectionDAG &DAG) const
{
DebugLoc DL = Op.getDebugLoc();
EVT VT = Op.getValueType();
EVT IntVT;
if (VT == MVT::f32) {
IntVT = MVT::i32;
} else if (VT == MVT::v4f32) {
IntVT = MVT::v4i32;
} else {
return Op;
}
LoadSDNode * LD = dyn_cast<LoadSDNode>(Op);
assert(LD);
SDValue NewLoad = DAG.getLoad (LD->getAddressingMode(),
LD->getExtensionType(), IntVT, DL,
LD->getChain(), LD->getBasePtr(),
LD->getOffset(), IntVT,
LD->getMemOperand());
SDValue Bitcast = DAG.getNode(ISD::BITCAST, DL, VT, NewLoad);
DAG.ReplaceAllUsesWith(Op.getValue(0).getNode(), &Bitcast);
return Op;
}
SDValue AMDGPUTargetLowering::LowerSELECT_CC(SDValue Op,
SelectionDAG &DAG) const
{

View file

@ -23,7 +23,6 @@ class AMDGPUTargetLowering : public AMDILTargetLowering
{
private:
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
SDValue BitcastLOAD(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;

View file

@ -203,9 +203,12 @@ bool R600CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
emit(inst);
break;
}
case AMDGPU::VTX_READ_PARAM_eg:
case AMDGPU::VTX_READ_GLOBAL_eg:
case AMDGPU::VTX_READ_GLOBAL_128_eg:
case AMDGPU::VTX_READ_PARAM_i32_eg:
case AMDGPU::VTX_READ_PARAM_f32_eg:
case AMDGPU::VTX_READ_GLOBAL_i32_eg:
case AMDGPU::VTX_READ_GLOBAL_f32_eg:
case AMDGPU::VTX_READ_GLOBAL_v4i32_eg:
case AMDGPU::VTX_READ_GLOBAL_v4f32_eg:
{
uint64_t InstWord01 = getBinaryCodeForInstr(MI);
uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset

View file

@ -253,7 +253,7 @@ void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBl
.addReg(AMDGPU::ALU_LITERAL_X)
.addImm(dword_offset * 4);
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::VTX_READ_PARAM_eg))
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::VTX_READ_PARAM_i32_eg))
.addOperand(MI->getOperand(0))
.addReg(PtrReg)
.addImm(0);

View file

@ -1021,14 +1021,6 @@ class VTX_READ_32_eg <bits<8> buffer_id, list<dag> pattern>
let DATA_FORMAT = 0xD; // COLOR_32
}
def VTX_READ_PARAM_eg : VTX_READ_32_eg <0,
[(set (i32 R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))]
>;
def VTX_READ_GLOBAL_eg : VTX_READ_32_eg <1,
[(set (i32 R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))]
>;
class VTX_READ_128_eg <bits<8> buffer_id, list<dag> pattern>
: VTX_READ_eg <buffer_id, (outs R600_Reg128:$dst), pattern> {
@ -1040,10 +1032,40 @@ class VTX_READ_128_eg <bits<8> buffer_id, list<dag> pattern>
let DATA_FORMAT = 0x22; // COLOR_32_32_32_32
}
def VTX_READ_GLOBAL_128_eg : VTX_READ_128_eg <1,
[(set (v4i32 R600_Reg128:$dst), (global_load ADDRVTX_READ:$ptr))]
//===----------------------------------------------------------------------===//
// VTX Read from parameter memory space
//===----------------------------------------------------------------------===//
class VTX_READ_PARAM_32_eg <ValueType vt> : VTX_READ_32_eg <0,
[(set (vt R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))]
>;
def VTX_READ_PARAM_i32_eg : VTX_READ_PARAM_32_eg<i32>;
def VTX_READ_PARAM_f32_eg : VTX_READ_PARAM_32_eg<f32>;
//===----------------------------------------------------------------------===//
// VTX Read from global memory space
//===----------------------------------------------------------------------===//
// 32-bit reads
class VTX_READ_GLOBAL_eg <ValueType vt> : VTX_READ_32_eg <1,
[(set (vt R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))]
>;
def VTX_READ_GLOBAL_i32_eg : VTX_READ_GLOBAL_eg<i32>;
def VTX_READ_GLOBAL_f32_eg : VTX_READ_GLOBAL_eg<f32>;
// 128-bit reads
class VTX_READ_GLOBAL_128_eg <ValueType vt> : VTX_READ_128_eg <1,
[(set (vt R600_Reg128:$dst), (global_load ADDRVTX_READ:$ptr))]
>;
def VTX_READ_GLOBAL_v4i32_eg : VTX_READ_GLOBAL_128_eg<v4i32>;
def VTX_READ_GLOBAL_v4f32_eg : VTX_READ_GLOBAL_128_eg<v4f32>;
}
let Predicates = [isCayman] in {

View file

@ -468,5 +468,10 @@ multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass dstClass,
>;
}
multiclass SMRD_32 <bits<5> op, string asm, RegisterClass dstClass> {
defm _F32 : SMRD_Helper <op, asm, dstClass, f32>;
defm _I32 : SMRD_Helper <op, asm, dstClass, i32>;
}
include "SIInstrFormats.td"
include "SIInstructions.td"

View file

@ -358,7 +358,8 @@ def TBUFFER_LOAD_FORMAT_XYZW : MTBUF_Load_Helper <0x00000003, "TBUFFER_LOAD_FORM
//def TBUFFER_STORE_FORMAT_XYZ : MTBUF_ <0x00000006, "TBUFFER_STORE_FORMAT_XYZ", []>;
//def TBUFFER_STORE_FORMAT_XYZW : MTBUF_ <0x00000007, "TBUFFER_STORE_FORMAT_XYZW", []>;
defm S_LOAD_DWORD : SMRD_Helper <0x00000000, "S_LOAD_DWORD", SReg_32, f32>;
defm S_LOAD_DWORD : SMRD_32 <0x00000000, "S_LOAD_DWORD", SReg_32>;
//def S_LOAD_DWORDX2 : SMRD_DWORDX2 <0x00000001, "S_LOAD_DWORDX2", []>;
defm S_LOAD_DWORDX4 : SMRD_Helper <0x00000002, "S_LOAD_DWORDX4", SReg_128, v4i32>;
defm S_LOAD_DWORDX8 : SMRD_Helper <0x00000003, "S_LOAD_DWORDX8", SReg_256, v8i32>;