diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2019-03-14 19:22:08 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2019-03-14 19:22:08 +0000 |
| commit | de1d5d3675992a60c95b17d70ea817468883c485 (patch) | |
| tree | 705e488bdb810e0a0cba00b3a36906e11285c1dd /llvm/lib/Transforms | |
| parent | 6e86216531e2c53f171aaf8b911327ab616c6c0d (diff) | |
| download | bcm5719-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.cpp | 15 |
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)); |

