summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2018-10-13 13:05:19 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2018-10-13 13:05:19 +0000
commitf64e654d62e64ac4a74a49ac78b5609a8bb548a1 (patch)
tree9b0150191ff1c7b3eed0426c5316648be0d14fd9 /llvm/lib/Target/X86
parentafead139cfcf85c5ebf7e440a7b3105538af87a2 (diff)
downloadbcm5719-llvm-f64e654d62e64ac4a74a49ac78b5609a8bb548a1.tar.gz
bcm5719-llvm-f64e654d62e64ac4a74a49ac78b5609a8bb548a1.zip
[X86][SSE] Improve CTTZ lowering when CTLZ is legal
If we have better CTLZ support than CTPOP, then use cttz(x) = width - ctlz(~x & (x - 1)) - and remove the CTTZ_ZERO_UNDEF handling as it no longer gives better codegen. Similar to rL344447, this is also closer to LegalizeDAG's approach llvm-svn: 344448
Diffstat (limited to 'llvm/lib/Target/X86')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp24
1 files changed, 13 insertions, 11 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 5fb3ece19f2..5f1e9ef1b03 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22982,20 +22982,22 @@ static SDValue LowerCTTZ(SDValue Op, const X86Subtarget &Subtarget,
if (VT.is256BitVector() && !Subtarget.hasInt256())
return Lower256IntUnary(Op, DAG);
- // cttz_undef(x) = (width - 1) - ctlz(x & -x)
- if (Op.getOpcode() == ISD::CTTZ_ZERO_UNDEF) {
- SDValue WidthMinusOne = DAG.getConstant(NumBits - 1, dl, VT);
- SDValue LSB = DAG.getNode(ISD::AND, dl, VT, N0,
- DAG.getNode(ISD::SUB, dl, VT, Zero, N0));
- return DAG.getNode(ISD::SUB, dl, VT, WidthMinusOne,
- DAG.getNode(ISD::CTLZ, dl, VT, LSB));
+ // Tmp = ~x & (x - 1)
+ SDValue One = DAG.getConstant(1, dl, VT);
+ SDValue Tmp = DAG.getNode(ISD::AND, dl, VT, DAG.getNOT(dl, N0, VT),
+ DAG.getNode(ISD::SUB, dl, VT, N0, One));
+
+ // cttz(x) = width - ctlz(~x & (x - 1))
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (TLI.isOperationLegal(ISD::CTLZ, VT) &&
+ !TLI.isOperationLegal(ISD::CTPOP, VT)) {
+ SDValue Width = DAG.getConstant(NumBits, dl, VT);
+ return DAG.getNode(ISD::SUB, dl, VT, Width,
+ DAG.getNode(ISD::CTLZ, dl, VT, Tmp));
}
// cttz(x) = ctpop(~x & (x - 1))
- SDValue One = DAG.getConstant(1, dl, VT);
- return DAG.getNode(ISD::CTPOP, dl, VT,
- DAG.getNode(ISD::AND, dl, VT, DAG.getNOT(dl, N0, VT),
- DAG.getNode(ISD::SUB, dl, VT, N0, One)));
+ return DAG.getNode(ISD::CTPOP, dl, VT, Tmp);
}
assert(Op.getOpcode() == ISD::CTTZ &&
OpenPOWER on IntegriCloud