mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
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:
parent
bbdf3af857
commit
49ae102ee3
7 changed files with 46 additions and 50 deletions
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue