summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-10-13 21:48:30 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-10-13 21:48:30 +0000
commita252138942d8d48eb31234e0da09d3d97cb6abad (patch)
treeeaabf3357117fd540cd950b358b119366ae26c27 /llvm/lib/Support/APInt.cpp
parenta562b46db736bdaa74e7c52a1eb7415561613836 (diff)
downloadbcm5719-llvm-a252138942d8d48eb31234e0da09d3d97cb6abad.tar.gz
bcm5719-llvm-a252138942d8d48eb31234e0da09d3d97cb6abad.zip
InstCombine: Don't miscompile (x lshr C1) udiv C2
We have a transform that changes: (x lshr C1) udiv C2 into: x udiv (C2 << C1) However, it is unsafe to do so if C2 << C1 discards any of C2's bits. This fixes PR21255. llvm-svn: 219634
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r--llvm/lib/Support/APInt.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 02778b2fc7c..c20eeb26948 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -2064,19 +2064,29 @@ APInt APInt::umul_ov(const APInt &RHS, bool &Overflow) const {
return Res;
}
-APInt APInt::sshl_ov(unsigned ShAmt, bool &Overflow) const {
- Overflow = ShAmt >= getBitWidth();
+APInt APInt::sshl_ov(const APInt &ShAmt, bool &Overflow) const {
+ Overflow = ShAmt.uge(getBitWidth());
if (Overflow)
- ShAmt = getBitWidth()-1;
+ return APInt(BitWidth, 0);
if (isNonNegative()) // Don't allow sign change.
- Overflow = ShAmt >= countLeadingZeros();
+ Overflow = ShAmt.uge(countLeadingZeros());
else
- Overflow = ShAmt >= countLeadingOnes();
+ Overflow = ShAmt.uge(countLeadingOnes());
return *this << ShAmt;
}
+APInt APInt::ushl_ov(const APInt &ShAmt, bool &Overflow) const {
+ Overflow = ShAmt.uge(getBitWidth());
+ if (Overflow)
+ return APInt(BitWidth, 0);
+
+ Overflow = ShAmt.ugt(countLeadingZeros());
+
+ return *this << ShAmt;
+}
+
OpenPOWER on IntegriCloud