summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Support/APInt.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 7b3be916f31..7e17e42dc91 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -1252,8 +1252,21 @@ APInt APInt::shlSlowCase(unsigned shiftAmt) const {
return Result;
}
+// Calculate the rotate amount modulo the bit width.
+static unsigned rotateModulo(unsigned BitWidth, const APInt &rotateAmt) {
+ unsigned rotBitWidth = rotateAmt.getBitWidth();
+ APInt rot = rotateAmt;
+ if (rotBitWidth < BitWidth) {
+ // Extend the rotate APInt, so that the urem doesn't divide by 0.
+ // e.g. APInt(1, 32) would give APInt(1, 0).
+ rot = rotateAmt.zext(BitWidth);
+ }
+ rot = rot.urem(APInt(rot.getBitWidth(), BitWidth));
+ return rot.getLimitedValue(BitWidth);
+}
+
APInt APInt::rotl(const APInt &rotateAmt) const {
- return rotl((unsigned)rotateAmt.getLimitedValue(BitWidth));
+ return rotl(rotateModulo(BitWidth, rotateAmt));
}
APInt APInt::rotl(unsigned rotateAmt) const {
@@ -1264,7 +1277,7 @@ APInt APInt::rotl(unsigned rotateAmt) const {
}
APInt APInt::rotr(const APInt &rotateAmt) const {
- return rotr((unsigned)rotateAmt.getLimitedValue(BitWidth));
+ return rotr(rotateModulo(BitWidth, rotateAmt));
}
APInt APInt::rotr(unsigned rotateAmt) const {
OpenPOWER on IntegriCloud