diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-05-08 15:49:10 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-05-08 15:49:10 +0000 |
commit | e3eec06ddeac74dde579f0e157034104e67d355e (patch) | |
tree | b7a910ffb3ee278f76a13313a9198edf850c5c9b /llvm/lib/Target | |
parent | 6c433713e91bfd28f4351f43bb90c4455cba8540 (diff) | |
download | bcm5719-llvm-e3eec06ddeac74dde579f0e157034104e67d355e.tar.gz bcm5719-llvm-e3eec06ddeac74dde579f0e157034104e67d355e.zip |
[AMDGPU] Reapplied BFE canonicalization from D60462
This was committed in rL358887 but reverted in rL360066 due to a x86 regression, really it should be have been pre-committed instead of being part of the SimplifyDemandedBits bitcast patch.
llvm-svn: 360263
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp index 994e912ac9c..409fbfa22f3 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -3202,30 +3202,44 @@ SDValue AMDGPUTargetLowering::performSraCombine(SDNode *N, SDValue AMDGPUTargetLowering::performSrlCombine(SDNode *N, DAGCombinerInfo &DCI) const { - if (N->getValueType(0) != MVT::i64) - return SDValue(); - - const ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1)); + auto *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1)); if (!RHS) return SDValue(); + EVT VT = N->getValueType(0); + SDValue LHS = N->getOperand(0); unsigned ShiftAmt = RHS->getZExtValue(); + SelectionDAG &DAG = DCI.DAG; + SDLoc SL(N); + + // fold (srl (and x, c1 << c2), c2) -> (and (srl(x, c2), c1) + // this improves the ability to match BFE patterns in isel. + if (LHS.getOpcode() == ISD::AND) { + if (auto *Mask = dyn_cast<ConstantSDNode>(LHS.getOperand(1))) { + if (Mask->getAPIntValue().isShiftedMask() && + Mask->getAPIntValue().countTrailingZeros() == ShiftAmt) { + return DAG.getNode( + ISD::AND, SL, VT, + DAG.getNode(ISD::SRL, SL, VT, LHS.getOperand(0), N->getOperand(1)), + DAG.getNode(ISD::SRL, SL, VT, LHS.getOperand(1), N->getOperand(1))); + } + } + } + + if (VT != MVT::i64) + return SDValue(); + if (ShiftAmt < 32) return SDValue(); // srl i64:x, C for C >= 32 // => // build_pair (srl hi_32(x), C - 32), 0 - - SelectionDAG &DAG = DCI.DAG; - SDLoc SL(N); - SDValue One = DAG.getConstant(1, SL, MVT::i32); SDValue Zero = DAG.getConstant(0, SL, MVT::i32); - SDValue VecOp = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, N->getOperand(0)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, - VecOp, One); + SDValue VecOp = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, LHS); + SDValue Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, VecOp, One); SDValue NewConst = DAG.getConstant(ShiftAmt - 32, SL, MVT::i32); SDValue NewShift = DAG.getNode(ISD::SRL, SL, MVT::i32, Hi, NewConst); |