From: Tom Stellard Date: Tue, 10 Jul 2012 15:15:49 +0000 (-0400) Subject: radeon/llvm: Use multiclasses for floating point loads X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=49ae102ee346d4be6a61ebdaba6e5d5ad8469407;p=mesa.git 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). --- diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp index ef5715fd5f0..b3d27f762e6 100644 --- a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp +++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp @@ -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(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 { diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.h b/src/gallium/drivers/radeon/AMDGPUISelLowering.h index 4d1a312ea5e..72342c99614 100644 --- a/src/gallium/drivers/radeon/AMDGPUISelLowering.h +++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.h @@ -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; diff --git a/src/gallium/drivers/radeon/R600CodeEmitter.cpp b/src/gallium/drivers/radeon/R600CodeEmitter.cpp index 4c7962bcee4..d882bb1e44a 100644 --- a/src/gallium/drivers/radeon/R600CodeEmitter.cpp +++ b/src/gallium/drivers/radeon/R600CodeEmitter.cpp @@ -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 diff --git a/src/gallium/drivers/radeon/R600ISelLowering.cpp b/src/gallium/drivers/radeon/R600ISelLowering.cpp index 00ab7519dd6..ee4fea88f5f 100644 --- a/src/gallium/drivers/radeon/R600ISelLowering.cpp +++ b/src/gallium/drivers/radeon/R600ISelLowering.cpp @@ -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); diff --git a/src/gallium/drivers/radeon/R600Instructions.td b/src/gallium/drivers/radeon/R600Instructions.td index a7d29fe5488..f96bd157da7 100644 --- a/src/gallium/drivers/radeon/R600Instructions.td +++ b/src/gallium/drivers/radeon/R600Instructions.td @@ -1021,14 +1021,6 @@ class VTX_READ_32_eg buffer_id, list 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 buffer_id, list pattern> : VTX_READ_eg { @@ -1040,10 +1032,40 @@ class VTX_READ_128_eg buffer_id, list 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 : 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; +def VTX_READ_PARAM_f32_eg : VTX_READ_PARAM_32_eg; + + +//===----------------------------------------------------------------------===// +// VTX Read from global memory space +//===----------------------------------------------------------------------===// + +// 32-bit reads + +class VTX_READ_GLOBAL_eg : 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; +def VTX_READ_GLOBAL_f32_eg : VTX_READ_GLOBAL_eg; + +// 128-bit reads + +class VTX_READ_GLOBAL_128_eg : 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; +def VTX_READ_GLOBAL_v4f32_eg : VTX_READ_GLOBAL_128_eg; + } let Predicates = [isCayman] in { diff --git a/src/gallium/drivers/radeon/SIInstrInfo.td b/src/gallium/drivers/radeon/SIInstrInfo.td index be08e8abbce..aac644369d9 100644 --- a/src/gallium/drivers/radeon/SIInstrInfo.td +++ b/src/gallium/drivers/radeon/SIInstrInfo.td @@ -468,5 +468,10 @@ multiclass SMRD_Helper op, string asm, RegisterClass dstClass, >; } +multiclass SMRD_32 op, string asm, RegisterClass dstClass> { + defm _F32 : SMRD_Helper ; + defm _I32 : SMRD_Helper ; +} + include "SIInstrFormats.td" include "SIInstructions.td" diff --git a/src/gallium/drivers/radeon/SIInstructions.td b/src/gallium/drivers/radeon/SIInstructions.td index a96d7839fba..e832ab50447 100644 --- a/src/gallium/drivers/radeon/SIInstructions.td +++ b/src/gallium/drivers/radeon/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>;