summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2016-01-18 22:09:04 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2016-01-18 22:09:04 +0000
commit33e3ecee0c44169f11d1fc4472250c1346e68a4e (patch)
treeaefe8d1832cb203a53914cc47e3ecd8bb4bf5432 /llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
parent6e3a45193aa927de0d4a677594f74c31cfc26727 (diff)
downloadbcm5719-llvm-33e3ecee0c44169f11d1fc4472250c1346e68a4e.tar.gz
bcm5719-llvm-33e3ecee0c44169f11d1fc4472250c1346e68a4e.zip
AMDGPU: Reduce 64-bit SRAs
llvm-svn: 258096
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 477851d4d3a..f3dfb2a19e0 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -378,6 +378,7 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM,
setTargetDAGCombine(ISD::AND);
setTargetDAGCombine(ISD::SHL);
+ setTargetDAGCombine(ISD::SRA);
setTargetDAGCombine(ISD::SRL);
setTargetDAGCombine(ISD::MUL);
setTargetDAGCombine(ISD::SELECT);
@@ -1193,6 +1194,22 @@ AMDGPUTargetLowering::split64BitValue(SDValue Op, SelectionDAG &DAG) const {
return std::make_pair(Lo, Hi);
}
+SDValue AMDGPUTargetLowering::getLoHalf64(SDValue Op, SelectionDAG &DAG) const {
+ SDLoc SL(Op);
+
+ SDValue Vec = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op);
+ const SDValue Zero = DAG.getConstant(0, SL, MVT::i32);
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, Zero);
+}
+
+SDValue AMDGPUTargetLowering::getHiHalf64(SDValue Op, SelectionDAG &DAG) const {
+ SDLoc SL(Op);
+
+ SDValue Vec = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op);
+ const SDValue One = DAG.getConstant(1, SL, MVT::i32);
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, One);
+}
+
SDValue AMDGPUTargetLowering::ScalarizeVectorLoad(const SDValue Op,
SelectionDAG &DAG) const {
LoadSDNode *Load = cast<LoadSDNode>(Op);
@@ -2626,6 +2643,43 @@ SDValue AMDGPUTargetLowering::performShlCombine(SDNode *N,
return DAG.getNode(ISD::BITCAST, SL, MVT::i64, Vec);
}
+SDValue AMDGPUTargetLowering::performSraCombine(SDNode *N,
+ DAGCombinerInfo &DCI) const {
+ if (N->getValueType(0) != MVT::i64)
+ return SDValue();
+
+ const ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ if (!RHS)
+ return SDValue();
+
+ SelectionDAG &DAG = DCI.DAG;
+ SDLoc SL(N);
+ unsigned RHSVal = RHS->getZExtValue();
+
+ // (sra i64:x, 32) -> build_pair x, (sra hi_32(x), 31)
+ if (RHSVal == 32) {
+ SDValue Hi = getHiHalf64(N->getOperand(0), DAG);
+ SDValue NewShift = DAG.getNode(ISD::SRA, SL, MVT::i32, Hi,
+ DAG.getConstant(31, SL, MVT::i32));
+
+ SDValue BuildVec = DAG.getNode(ISD::BUILD_VECTOR, SL, MVT::v2i32,
+ Hi, NewShift);
+ return DAG.getNode(ISD::BITCAST, SL, MVT::i64, BuildVec);
+ }
+
+ // (sra i64:x, 63) -> build_pair (sra hi_32(x), 31), (sra hi_32(x), 31)
+ if (RHSVal == 63) {
+ SDValue Hi = getHiHalf64(N->getOperand(0), DAG);
+ SDValue NewShift = DAG.getNode(ISD::SRA, SL, MVT::i32, Hi,
+ DAG.getConstant(31, SL, MVT::i32));
+ SDValue BuildVec = DAG.getNode(ISD::BUILD_VECTOR, SL, MVT::v2i32,
+ NewShift, NewShift);
+ return DAG.getNode(ISD::BITCAST, SL, MVT::i64, BuildVec);
+ }
+
+ return SDValue();
+}
+
SDValue AMDGPUTargetLowering::performSrlCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
if (N->getValueType(0) != MVT::i64)
@@ -2804,6 +2858,12 @@ SDValue AMDGPUTargetLowering::PerformDAGCombine(SDNode *N,
return performSrlCombine(N, DCI);
}
+ case ISD::SRA: {
+ if (DCI.getDAGCombineLevel() < AfterLegalizeDAG)
+ break;
+
+ return performSraCombine(N, DCI);
+ }
case ISD::AND: {
if (DCI.getDAGCombineLevel() < AfterLegalizeDAG)
break;
OpenPOWER on IntegriCloud