diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-11-05 07:28:37 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-11-05 07:28:37 +0000 |
| commit | e9ff0eaf5b025b630ae1d1fa73a6c757a8223184 (patch) | |
| tree | 8652000271009b88c462753e8dfc9b518691f171 /llvm/lib/Transforms | |
| parent | 904dbb4a27db827319aa1058560b16384e32615e (diff) | |
| download | bcm5719-llvm-e9ff0eaf5b025b630ae1d1fa73a6c757a8223184.tar.gz bcm5719-llvm-e9ff0eaf5b025b630ae1d1fa73a6c757a8223184.zip | |
Turn srem -> urem when neither input has their sign bit set. This triggers
8 times in vortex, allowing the srems to be turned into shrs:
OLD: %tmp.104 = rem int %tmp.5.i37, 16 ; <int> [#uses=1]
NEW: %tmp.104 = rem uint %tmp.5.i37, 16 ; <uint> [#uses=0]
OLD: %tmp.98 = rem int %tmp.5.i24, 16 ; <int> [#uses=1]
NEW: %tmp.98 = rem uint %tmp.5.i24, 16 ; <uint> [#uses=0]
OLD: %tmp.91 = rem int %tmp.5.i19, 8 ; <int> [#uses=1]
NEW: %tmp.91 = rem uint %tmp.5.i19, 8 ; <uint> [#uses=0]
OLD: %tmp.88 = rem int %tmp.5.i14, 8 ; <int> [#uses=1]
NEW: %tmp.88 = rem uint %tmp.5.i14, 8 ; <uint> [#uses=0]
OLD: %tmp.85 = rem int %tmp.5.i9, 1024 ; <int> [#uses=2]
NEW: %tmp.85 = rem uint %tmp.5.i9, 1024 ; <uint> [#uses=0]
OLD: %tmp.82 = rem int %tmp.5.i, 512 ; <int> [#uses=2]
NEW: %tmp.82 = rem uint %tmp.5.i1, 512 ; <uint> [#uses=0]
OLD: %tmp.48.i = rem int %tmp.5.i.i161, 4 ; <int> [#uses=1]
NEW: %tmp.48.i = rem uint %tmp.5.i.i161, 4 ; <uint> [#uses=0]
OLD: %tmp.20.i2 = rem int %tmp.5.i.i, 4 ; <int> [#uses=1]
NEW: %tmp.20.i2 = rem uint %tmp.5.i.i, 4 ; <uint> [#uses=0]
it also occurs 9 times in gcc, but with odd constant divisors (1009 and 61)
so the payoff isn't as great.
llvm-svn: 24189
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 1db2df25068..4a764c996d7 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1246,7 +1246,7 @@ Instruction *InstCombiner::visitDiv(BinaryOperator &I) { Instruction *InstCombiner::visitRem(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - if (I.getType()->isSigned()) + if (I.getType()->isSigned()) { if (Value *RHSNeg = dyn_castNegVal(Op1)) if (!isa<ConstantSInt>(RHSNeg) || cast<ConstantSInt>(RHSNeg)->getValue() > 0) { @@ -1255,6 +1255,24 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) { I.setOperand(1, RHSNeg); return &I; } + + // If the top bits of both operands are zero (i.e. we can prove they are + // unsigned inputs), turn this into a urem. + ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType()); + if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) { + const Type *NTy = Op0->getType()->getUnsignedVersion(); + Instruction *LHS = new CastInst(Op0, NTy, Op0->getName()); + InsertNewInstBefore(LHS, I); + Value *RHS; + if (Constant *R = dyn_cast<Constant>(Op1)) + RHS = ConstantExpr::getCast(R, NTy); + else + RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I); + Instruction *Rem = BinaryOperator::createRem(LHS, RHS, I.getName()); + InsertNewInstBefore(Rem, I); + return new CastInst(Rem, I.getType()); + } + } if (isa<UndefValue>(Op0)) // undef % X -> 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); |

