Turn srem -> urem when neither input has their sign bit set. This triggers
authorChris Lattner <sabre@nondot.org>
Sat, 5 Nov 2005 07:28:37 +0000 (07:28 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 5 Nov 2005 07:28:37 +0000 (07:28 +0000)
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

lib/Transforms/Scalar/InstructionCombining.cpp

index 1db2df250687441ff6069df12bd71c93acd4e5e3..4a764c996d7d54a5d64a2b28cf771ffbb8bea174 100644 (file)
@@ -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()));