aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-04-02 06:11:11 +0000
committerChris Lattner <sabre@nondot.org>2006-04-02 06:11:11 +0000
commit350bec0fb9680b849942052b25f838d8ad10c743 (patch)
tree36dc6771029d2cbf684d3fb0104a1fdfd6d81b03 /lib/CodeGen
parent4132afb0d2398ae6d211edc9ffc9d2ec25b7abb2 (diff)
downloadexternal_llvm-350bec0fb9680b849942052b25f838d8ad10c743.zip
external_llvm-350bec0fb9680b849942052b25f838d8ad10c743.tar.gz
external_llvm-350bec0fb9680b849942052b25f838d8ad10c743.tar.bz2
Add a little dag combine to compile this:
int %AreSecondAndThirdElementsBothNegative(<4 x float>* %in) { entry: %tmp1 = load <4 x float>* %in ; <<4 x float>> [#uses=1] %tmp = tail call int %llvm.ppc.altivec.vcmpgefp.p( int 1, <4 x float> < float 0x7FF8000000000000, float 0.000000e+00, float 0.000000e+00, float 0x7FF8000000000000 >, <4 x float> %tmp1 ) ; <int> [#uses=1] %tmp = seteq int %tmp, 0 ; <bool> [#uses=1] %tmp3 = cast bool %tmp to int ; <int> [#uses=1] ret int %tmp3 } into this: _AreSecondAndThirdElementsBothNegative: mfspr r2, 256 oris r4, r2, 49152 mtspr 256, r4 li r4, lo16(LCPI1_0) lis r5, ha16(LCPI1_0) lvx v0, 0, r3 lvx v1, r5, r4 vcmpgefp. v0, v1, v0 mfcr r3, 2 rlwinm r3, r3, 27, 31, 31 mtspr 256, r2 blr instead of this: _AreSecondAndThirdElementsBothNegative: mfspr r2, 256 oris r4, r2, 49152 mtspr 256, r4 li r4, lo16(LCPI1_0) lis r5, ha16(LCPI1_0) lvx v0, 0, r3 lvx v1, r5, r4 vcmpgefp. v0, v1, v0 mfcr r3, 2 rlwinm r3, r3, 27, 31, 31 xori r3, r3, 1 cntlzw r3, r3 srwi r3, r3, 5 mtspr 256, r2 blr git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27356 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index cf585a8..f0003f0 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1601,6 +1601,39 @@ SDOperand DAGCombiner::visitSRL(SDNode *N) {
return DAG.getNode(ISD::SRL, VT, N0.getOperand(0),
DAG.getConstant(c1 + c2, N1.getValueType()));
}
+
+ // fold (srl (ctlz x), "5") -> x iff x has one bit set (the low bit).
+ if (N1C && N0.getOpcode() == ISD::CTLZ &&
+ N1C->getValue() == Log2_32(MVT::getSizeInBits(VT))) {
+ uint64_t KnownZero, KnownOne, Mask = MVT::getIntVTBitMask(VT);
+ TLI.ComputeMaskedBits(N0.getOperand(0), Mask, KnownZero, KnownOne);
+
+ // If any of the input bits are KnownOne, then the input couldn't be all
+ // zeros, thus the result of the srl will always be zero.
+ if (KnownOne) return DAG.getConstant(0, VT);
+
+ // If all of the bits input the to ctlz node are known to be zero, then
+ // the result of the ctlz is "32" and the result of the shift is one.
+ uint64_t UnknownBits = ~KnownZero & Mask;
+ if (UnknownBits == 0) return DAG.getConstant(1, VT);
+
+ // Otherwise, check to see if there is exactly one bit input to the ctlz.
+ if ((UnknownBits & (UnknownBits-1)) == 0) {
+ // Okay, we know that only that the single bit specified by UnknownBits
+ // could be set on input to the CTLZ node. If this bit is set, the SRL
+ // will return 0, if it is clear, it returns 1. Change the CTLZ/SRL pair
+ // to an SRL,XOR pair, which is likely to simplify more.
+ unsigned ShAmt = CountTrailingZeros_64(UnknownBits);
+ SDOperand Op = N0.getOperand(0);
+ if (ShAmt) {
+ Op = DAG.getNode(ISD::SRL, VT, Op,
+ DAG.getConstant(ShAmt, TLI.getShiftAmountTy()));
+ AddToWorkList(Op.Val);
+ }
+ return DAG.getNode(ISD::XOR, VT, Op, DAG.getConstant(1, VT));
+ }
+ }
+
return SDOperand();
}