[llvm-commits] REM Patch

Chris Lattner clattner at apple.com
Wed Nov 1 15:13:04 PST 2006


On Oct 31, 2006, at 3:01 PM, Reid Spencer wrote:

> Chris,
>
> Here's the patch for conversion of Rem -> [USF]Rem instructions.   
> Please
> review at your earliest convenience. This passes dejagnu and llvm-test
> suites.  I've reviewed and modified this patch to make it as simple to
> review as possible. Fortunately its a lot simpler than DIV.

Looks good.  Some comments: LangRef says that rem can be applied to  
vectors, but the asmparser rejects them, please update LangRef.


Some comments about instcombine below, prefixed by ***.  After making  
these changes and testing them, please commit.

-Chris


***This xform (visitURem):
+    if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) {
+      // X mul (C1 urem C2) --> 0  iff  C1 urem C2 == 0
+      if (ConstantExpr::getURem(GetFactor(Op0I), RHS)->isNullValue())
          return ReplaceInstUsesWith(I, Constant::getNullValue 
(I.getType()));
      }
    }

*** is doing "(X mul C1) urem C2 --> 0  iff  C1 urem C2 == 0"
please update the comment.

This xform also applies in the srem case, where the code is copied,  
but the comment unmodified.  Please move it to intcommon.



    if (Instruction *RHSI = dyn_cast<Instruction>(I.getOperand(1))) {
-    // Turn A % (C << N), where C is 2^k, into A & ((C << N)-1)  
[urem only].
-    if (I.getType()->isUnsigned() &&
-        RHSI->getOpcode() == Instruction::Shl &&
-        isa<ConstantInt>(RHSI->getOperand(0)) &&
-        RHSI->getOperand(0)->getType()->isUnsigned()) {
+    // Turn A urem (2^C << N) ->  A & ((C << N)-1) [urem only].
+    if (RHSI->getOpcode() == Instruction::Shl &&
+        isa<ConstantInt>(RHSI->getOperand(0))) {

*** Please change the comment back, your change is not correct.  You  
can drop 'urem only'.


+  // If the top bits of both operands are zero (i.e. we can prove  
they are
+  // unsigned inputs), turn this into a urem.
+  uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
+  if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
+    // X srem Y -> X urem Y, iff X and Y don't have sign bit set
+    return BinaryOperator::createURem(Op0, Op1, I.getName());;
    }
*** ";;" -> ";"






@@ -4564,41 +4608,24 @@ Instruction *InstCombiner::visitSetCondI

        // If the first operand is (add|sub|and|or|xor|rem) with a  
constant, and
        // the second operand is a constant, simplify a bit.
        if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0)) {
          switch (BO->getOpcode()) {
-#if 0
+        case Instruction::URem:
+          break;
*** No need for this case stmt, just remove it.

          case Instruction::SRem:
            // If we have a signed (X % (2^c)) == 0, turn it into an  
unsigned one.
            if (CI->isNullValue() && isa<ConstantInt>(BO->getOperand 
(1)) &&
                BO->hasOneUse()) {
              int64_t V = cast<ConstantInt>(BO->getOperand(1))- 
 >getSExtValue();
              if (V > 1 && isPowerOf2_64(V)) {
                unsigned L2 = Log2_64(V);
                const Type *UTy = BO->getType()->getUnsignedVersion();
                Value *NewX = InsertNewInstBefore(new CastInst(BO- 
 >getOperand(0),
                                                               UTy,  
"tmp"), I);
                Constant *RHSCst = ConstantInt::get(UTy, 1ULL << L2);
-              Value *NewRem =InsertNewInstBefore 
(BinaryOperator::createRem(NewX,
+              Value *NewRem =InsertNewInstBefore 
(BinaryOperator::createURem(NewX,
                                                      RHSCst, BO- 
 >getName()), I);
                return BinaryOperator::create(I.getOpcode(), NewRem,
                                              Constant::getNullValue 
(UTy));
              }
            }
*** There is no need to insert the casts here.  It should just  
replace the srem with a urem in place, no need to change the sign of  
the inputs.  The old code needed the casts because the sign of the  
operation was tied to the sign of the inputs.





More information about the llvm-commits mailing list