[llvm-commits] [llvm] r120028 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/InstCombine/InstCombineShifts.cpp test/Transforms/InstCombine/shift.ll
Frits van Bommel
fvbommel at gmail.com
Tue Nov 23 11:56:11 PST 2010
On Tue, Nov 23, 2010 at 7:52 PM, Benjamin Kramer
<benny.kra at googlemail.com> wrote:
> Author: d0k
> Date: Tue Nov 23 12:52:42 2010
> New Revision: 120028
>
> URL: http://llvm.org/viewvc/llvm-project?rev=120028&view=rev
> Log:
> InstCombine: Reduce "X shift (A srem B)" to "X shift (A urem B)" iff B is positive.
>
> This allows to transform the rem in "1 << ((int)x % 8);" to an and.
Is this still worth it if the srem has multiple uses?
If the srem isn't optimized out completely you'd end up doing extra work here.
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp Tue Nov 23 12:52:42 2010
> @@ -53,6 +53,21 @@
> if (ConstantInt *CUI = dyn_cast<ConstantInt>(Op1))
> if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I))
> return Res;
> +
> + // X shift (A srem B) -> X shift (A urem B) iff B is positive.
> + // Because shifts by negative values are undefined.
> + if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op1))
> + if (BO->getOpcode() == Instruction::SRem && BO->getType()->isIntegerTy()) {
Maybe add a "&& BO->hasOneUse()" test here?
> + // Make sure the divisor's sign bit is zero.
> + APInt Mask = APInt::getSignBit(BO->getType()->getPrimitiveSizeInBits());
> + if (MaskedValueIsZero(BO->getOperand(1), Mask)) {
> + Value *URem = Builder->CreateURem(BO->getOperand(0), BO->getOperand(1),
> + BO->getName());
> + I.setOperand(1, URem);
> + return &I;
> + }
> + }
> +
> return 0;
> }
More information about the llvm-commits
mailing list