[PATCH] D54954: [DAGCombiner] guard against an oversized shift crash
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 27 08:29:10 PST 2018
spatel created this revision.
spatel added reviewers: efriedma, craig.topper.
Herald added a subscriber: mcrosier.
This change prevents the crash noted in the post-commit comments for rL347478 <https://reviews.llvm.org/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 <https://reviews.llvm.org/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.
https://reviews.llvm.org/D54954
Files:
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6098,16 +6098,21 @@
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.
+ unsigned ShiftAmt = ShiftC->getZExtValue();
+ 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));
+ }
}
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54954.175489.patch
Type: text/x-patch
Size: 1846 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181127/066afc6c/attachment.bin>
More information about the llvm-commits
mailing list