diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-10-10 17:52:02 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-10-10 17:52:02 +0000 |
commit | 7b904ce7246b7cde2d716eefafd4ef2ce2b3234a (patch) | |
tree | 20fd33656a1cb4a032f6886f498bf6e7923403bb /llvm/lib/CodeGen/SelectionDAG | |
parent | 6a2eff1e68a269647b7f8e23842120738b139c11 (diff) | |
download | bcm5719-llvm-7b904ce7246b7cde2d716eefafd4ef2ce2b3234a.tar.gz bcm5719-llvm-7b904ce7246b7cde2d716eefafd4ef2ce2b3234a.zip |
[DAGCombiner] fold select-of-constants to shift
This reverses the scalar canonicalization proposed in D63382.
Pre: isPowerOf2(C1)
%r = select i1 %cond, i32 C1, i32 0
=>
%z = zext i1 %cond to i32
%r = shl i32 %z, log2(C1)
https://rise4fun.com/Alive/Z50
x86 already tries to fold this pattern, but it isn't done
uniformly, so we still see a diff. AArch64 probably should
enable the TLI hook to benefit too, but that's a follow-on.
llvm-svn: 374397
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 377c6086b1a..41303921d87 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -8221,10 +8221,11 @@ SDValue DAGCombiner::foldSelectOfConstants(SDNode *N) { return Cond; } - // For any constants that differ by 1, we can transform the select into an - // extend and add. Use a target hook because some targets may prefer to - // transform in the other direction. + // Use a target hook because some targets may prefer to transform in the + // other direction. if (TLI.convertSelectOfConstantsToMath(VT)) { + // For any constants that differ by 1, we can transform the select into an + // extend and add. const APInt &C1Val = C1->getAPIntValue(); const APInt &C2Val = C2->getAPIntValue(); if (C1Val - 1 == C2Val) { @@ -8239,6 +8240,14 @@ SDValue DAGCombiner::foldSelectOfConstants(SDNode *N) { Cond = DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Cond); return DAG.getNode(ISD::ADD, DL, VT, Cond, N2); } + + // select Cond, Pow2, 0 --> (zext Cond) << log2(Pow2) + if (C1Val.isPowerOf2() && C2Val.isNullValue()) { + if (VT != MVT::i1) + Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Cond); + SDValue ShAmtC = DAG.getConstant(C1Val.exactLogBase2(), DL, VT); + return DAG.getNode(ISD::SHL, DL, VT, Cond, ShAmtC); + } } return SDValue(); |