From b66ef1f48c946fdb0762e0092fa13a6f53e53e90 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 27 Jun 2012 21:10:42 +0000 Subject: [PATCH] radeon/llvm: Handle floating point loads on R600 --- .../drivers/radeon/AMDGPUISelLowering.cpp | 30 +++++++++++++++++++ .../drivers/radeon/AMDGPUISelLowering.h | 1 + 2 files changed, 31 insertions(+) diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp index 544de0fa312..f14900450ae 100644 --- a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp +++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp @@ -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(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 72342c99614..4d1a312ea5e 100644 --- a/src/gallium/drivers/radeon/AMDGPUISelLowering.h +++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.h @@ -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; -- 2.30.2