radeon/llvm: Use multiclasses for floating point loads
authorTom Stellard <thomas.stellard@amd.com>
Tue, 10 Jul 2012 15:15:49 +0000 (11:15 -0400)
committerTom Stellard <thomas.stellard@amd.com>
Wed, 11 Jul 2012 17:47:20 +0000 (17:47 +0000)
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).

src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
src/gallium/drivers/radeon/AMDGPUISelLowering.h
src/gallium/drivers/radeon/R600CodeEmitter.cpp
src/gallium/drivers/radeon/R600ISelLowering.cpp
src/gallium/drivers/radeon/R600Instructions.td
src/gallium/drivers/radeon/SIInstrInfo.td
src/gallium/drivers/radeon/SIInstructions.td

index ef5715fd5f0c90c8ddb35ba0b766cdecaec8a837..b3d27f762e67ebc46eca0c7adf23bba91bcb4f15 100644 (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
 {
index 4d1a312ea5eabae4a58bb25c3c86cad88d3f3494..72342c996147174c9a3bbaf2b357d5b9f4d48feb 100644 (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;
 
index 4c7962bcee481edab995a17c030ff4d356859350..d882bb1e44a4178b2610d6be69532b7608ad7aab 100644 (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
index 00ab7519dd61b4717ce65db80a47b872e29a145d..ee4fea88f5f426a91aa3d3f8b68c3ce907fa8594 100644 (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);
index a7d29fe54885369c9cb3cff8e45aafe0d9766fa4..f96bd157da7190083975a415dd9f150bcfe6e9ae 100644 (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 {
index be08e8abbceac634a553704d81a001acf7b2a083..aac644369d95dc29858442280647d1bcae52f81c 100644 (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"
index a96d7839fba70c33444c53e9e6d0f07e14c02150..e832ab5044724f3e527caea0e9f2a30246416d9f 100644 (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>;