radeon/llvm: Handle floating point loads on R600
authorTom Stellard <thomas.stellard@amd.com>
Wed, 27 Jun 2012 21:10:42 +0000 (21:10 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Fri, 29 Jun 2012 18:46:18 +0000 (18:46 +0000)
src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
src/gallium/drivers/radeon/AMDGPUISelLowering.h

index 544de0fa3121d56177ca342468b310cfa04b128d..f14900450aec8baa3da2eacaebee93e3a331f6dd 100644 (file)
@@ -33,6 +33,7 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
   setOperationAction(ISD::FEXP2,  MVT::f32, Legal);
   setOperationAction(ISD::FRINT,  MVT::f32, Legal);
 
+  setOperationAction(ISD::LOAD, MVT::f32, Custom);
 
   setOperationAction(ISD::UDIV, MVT::i32, Expand);
   setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
@@ -45,6 +46,7 @@ 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);
   }
@@ -127,6 +129,34 @@ 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 {
+    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 72342c996147174c9a3bbaf2b357d5b9f4d48feb..4d1a312ea5eabae4a58bb25c3c86cad88d3f3494 100644 (file)
@@ -23,6 +23,7 @@ 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;