[APInt] Fix rotl/rotr when the shift amount is greater than the total bit width.

Review: https://reviews.llvm.org/D27749


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294295 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Joey Gouly
2017-02-07 11:58:22 +00:00
parent 7085bdc3ce
commit f83a9ee2df
2 changed files with 67 additions and 4 deletions
+15 -2
View File
@@ -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 {