summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-03-14 19:22:08 +0000
committerSanjay Patel <spatel@rotateright.com>2019-03-14 19:22:08 +0000
commitde1d5d3675992a60c95b17d70ea817468883c485 (patch)
tree705e488bdb810e0a0cba00b3a36906e11285c1dd /llvm/lib/Transforms
parent6e86216531e2c53f171aaf8b911327ab616c6c0d (diff)
downloadbcm5719-llvm-de1d5d3675992a60c95b17d70ea817468883c485.tar.gz
bcm5719-llvm-de1d5d3675992a60c95b17d70ea817468883c485.zip
[InstCombine] canonicalize funnel shift constant shift amount to be modulo bitwidth
The shift argument is defined to be modulo the bitwidth, so if that argument is a constant, we can always reduce the constant to its minimal form to allow better CSE and other follow-on transforms. We need to be careful to ignore constant expressions here, or we will likely infinite loop. I'm adding a general vector constant query for that case. Differential Revision: https://reviews.llvm.org/D59374 llvm-svn: 356192
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index dc8fd4766d4..3c8898004bb 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1994,10 +1994,22 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
case Intrinsic::fshl:
case Intrinsic::fshr: {
+ // Canonicalize a shift amount constant operand to be modulo the bit-width.
+ unsigned BitWidth = II->getType()->getScalarSizeInBits();
+ Constant *ShAmtC;
+ if (match(II->getArgOperand(2), m_Constant(ShAmtC)) &&
+ !isa<ConstantExpr>(ShAmtC) && !ShAmtC->containsConstantExpression()) {
+ Constant *WidthC = ConstantInt::get(II->getType(), BitWidth);
+ Constant *ModuloC = ConstantExpr::getURem(ShAmtC, WidthC);
+ if (ModuloC != ShAmtC) {
+ II->setArgOperand(2, ModuloC);
+ return II;
+ }
+ }
+
const APInt *SA;
if (match(II->getArgOperand(2), m_APInt(SA))) {
Value *Op0 = II->getArgOperand(0), *Op1 = II->getArgOperand(1);
- unsigned BitWidth = SA->getBitWidth();
uint64_t ShiftAmt = SA->urem(BitWidth);
assert(ShiftAmt != 0 && "SimplifyCall should have handled zero shift");
// Normalize to funnel shift left.
@@ -2020,7 +2032,6 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
// The shift amount (operand 2) of a funnel shift is modulo the bitwidth,
// so only the low bits of the shift amount are demanded if the bitwidth is
// a power-of-2.
- unsigned BitWidth = II->getType()->getScalarSizeInBits();
if (!isPowerOf2_32(BitWidth))
break;
APInt Op2Demanded = APInt::getLowBitsSet(BitWidth, Log2_32_Ceil(BitWidth));
OpenPOWER on IntegriCloud