mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-19 19:29:31 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24189 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a5e5bff8b8
commit
11a49f2c0d
@ -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()));
|
||||
|
Loading…
Reference in New Issue
Block a user