summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-10-10 17:52:02 +0000
committerSanjay Patel <spatel@rotateright.com>2019-10-10 17:52:02 +0000
commit7b904ce7246b7cde2d716eefafd4ef2ce2b3234a (patch)
tree20fd33656a1cb4a032f6886f498bf6e7923403bb /llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
parent6a2eff1e68a269647b7f8e23842120738b139c11 (diff)
downloadbcm5719-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/DAGCombiner.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp15
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();
OpenPOWER on IntegriCloud