[llvm-commits] REM Patch

Reid Spencer rspencer at reidspencer.com
Wed Nov 1 16:41:29 PST 2006


On Wed, 2006-11-01 at 15:13 -0800, Chris Lattner wrote:
> 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.

Done.

> 
> 
> 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.

Done.

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

Done.

>     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'.

Done.

> 
> 
> +  // 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());;
>     }
> *** ";;" -> ";"

Done.

> 
> @@ -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.
> 

Done.

>           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.

Right. Done.

Reid.




More information about the llvm-commits mailing list