summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-12-02 13:33:56 +0000
committerSanjay Patel <spatel@rotateright.com>2018-12-02 13:33:56 +0000
commit2daceedf9279621bb4942b0dc583542c260d7d19 (patch)
tree728d4aa6126f24ef07d0a71c8a2a6041105f136b
parent7d82d37854f56898e174c0807ae2b75772c28d1d (diff)
downloadbcm5719-llvm-2daceedf9279621bb4942b0dc583542c260d7d19.tar.gz
bcm5719-llvm-2daceedf9279621bb4942b0dc583542c260d7d19.zip
[DAGCombiner] guard against an oversized shift crash
This change prevents the crash noted in the post-commit comments for rL347478 : http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20181119/605166.html We can't guarantee that an oversized shift amount is folded away, so we have to check for it. Note that I committed an incomplete fix for that crash with: rL347502 But as discussed here: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20181126/605679.html ...we have to try harder. So I'm not sure how to expose the bug now (and apparently no fuzzers have found a way yet either). On the plus side, we have discovered that we're missing real optimizations by not simplifying nodes sooner, so the earlier fix still has value, and there's likely more value in extending that so we can simplify more opcodes and simplify when doing RAUW and/or putting nodes on the combiner worklist. Differential Revision: https://reviews.llvm.org/D54954 llvm-svn: 348089
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp23
1 files changed, 14 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 61c833043fa..06e3b9a3840 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6098,16 +6098,21 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
if ((N0Opcode == ISD::SRL || N0Opcode == ISD::SHL) && N0.hasOneUse()) {
ConstantSDNode *XorC = isConstOrConstSplat(N1);
ConstantSDNode *ShiftC = isConstOrConstSplat(N0.getOperand(1));
+ unsigned BitWidth = VT.getScalarSizeInBits();
if (XorC && ShiftC) {
- APInt Ones = APInt::getAllOnesValue(VT.getScalarSizeInBits());
- Ones = N0Opcode == ISD::SHL ? Ones.shl(ShiftC->getZExtValue())
- : Ones.lshr(ShiftC->getZExtValue());
- if (XorC->getAPIntValue() == Ones) {
- // If the xor constant is a shifted -1, do a 'not' before the shift:
- // xor (X << ShiftC), XorC --> (not X) << ShiftC
- // xor (X >> ShiftC), XorC --> (not X) >> ShiftC
- SDValue Not = DAG.getNOT(DL, N0.getOperand(0), VT);
- return DAG.getNode(N0Opcode, DL, VT, Not, N0.getOperand(1));
+ // Don't crash on an oversized shift. We can not guarantee that a bogus
+ // shift has been simplified to undef.
+ uint64_t ShiftAmt = ShiftC->getLimitedValue();
+ if (ShiftAmt < BitWidth) {
+ APInt Ones = APInt::getAllOnesValue(BitWidth);
+ Ones = N0Opcode == ISD::SHL ? Ones.shl(ShiftAmt) : Ones.lshr(ShiftAmt);
+ if (XorC->getAPIntValue() == Ones) {
+ // If the xor constant is a shifted -1, do a 'not' before the shift:
+ // xor (X << ShiftC), XorC --> (not X) << ShiftC
+ // xor (X >> ShiftC), XorC --> (not X) >> ShiftC
+ SDValue Not = DAG.getNOT(DL, N0.getOperand(0), VT);
+ return DAG.getNode(N0Opcode, DL, VT, Not, N0.getOperand(1));
+ }
}
}
}
OpenPOWER on IntegriCloud