mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
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 llvm-svn: 27356
This commit is contained in:
parent
42a1e621f1
commit
dbdc830c83
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user