[llvm-commits] [llvm] r169025 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Michael Ilseman milseman at apple.com
Fri Nov 30 11:19:17 PST 2012


Very minor tweak:

> +      Instruction *FMul = dyn_cast<Instruction>(FMulVal);
> +      assert(FMul && "Must be instruction as Log2 is instruction");

You can write this as:

assert(isa<Instruction>(FMulVal) && "Must be instruction as Log2 is instruction");
Instruction *FMul = cast<Instruction>(FMulVal);

dyn_cast consists of both an isa<> followed by a cast<>. If you're just asserting, then you can split it out yourself to make non-assert builds just do the cast<>.

Thanks for the fast-math contribution!

On Nov 30, 2012, at 11:09 AM, Pedro Artigas <partigas at apple.com> wrote:

> Author: partigas
> Date: Fri Nov 30 13:09:41 2012
> New Revision: 169025
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=169025&view=rev
> Log:
> Add fast math inst combine X*log2(Y*0.5)-->X*log2(Y)-X
> 
> reviewed by Michael Ilseman <milseman at apple.com>
> 
> 
> Modified:
>    llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
> 
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=169025&r1=169024&r2=169025&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Fri Nov 30 13:09:41 2012
> @@ -284,6 +284,83 @@
>     if (Value *Op1v = dyn_castFNegVal(Op1))
>       return BinaryOperator::CreateFMul(Op0v, Op1v);
> 
> +  // Under unsafe algebra do:
> +  // X * log2(0.5*Y) = X*log2(Y) - X
> +  if (I.hasUnsafeAlgebra()) {
> +    Value *OpX = NULL;
> +    Value *OpY = NULL;
> +    IntrinsicInst *Log2;
> +    if (Op0->hasOneUse()) {
> +      if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op0)) {
> +        if (II->getIntrinsicID() == Intrinsic::log2 && 
> +            II->hasUnsafeAlgebra())
> +        {
> +          Log2 = II;
> +          Value *OpLog2Of = II->getArgOperand(0);
> +          if (OpLog2Of->hasOneUse()) {
> +            if (Instruction *I = dyn_cast<Instruction>(OpLog2Of)) {
> +              if (I->getOpcode() == Instruction::FMul &&
> +                  I->hasUnsafeAlgebra())
> +              {
> +                ConstantFP *CFP = dyn_cast<ConstantFP>(I->getOperand(0));
> +                if (CFP && CFP->isExactlyValue(0.5)) {
> +                  OpY = I->getOperand(1);
> +                  OpX = Op1;
> +                } else {
> +                  CFP = dyn_cast<ConstantFP>(I->getOperand(1));
> +                  if (CFP && CFP->isExactlyValue(0.5)) {
> +                    OpY = I->getOperand(0);
> +                    OpX = Op1;
> +                  }
> +                }
> +              }
> +            }
> +          }
> +        }
> +      }
> +    }
> +    if (Op1->hasOneUse()) {
> +      if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op1)) {
> +        if (II->getIntrinsicID() == Intrinsic::log2 &&
> +            II->hasUnsafeAlgebra()) 
> +        {
> +          Log2 = II;
> +          Value *OpLog2Of = II->getArgOperand(0);
> +          if (OpLog2Of->hasOneUse()) {
> +            if (Instruction *I = dyn_cast<Instruction>(OpLog2Of)) {
> +              if (I->getOpcode() == Instruction::FMul &&
> +                  I->hasUnsafeAlgebra()) 
> +              {
> +                ConstantFP *CFP = dyn_cast<ConstantFP>(I->getOperand(0));
> +                if (CFP && CFP->isExactlyValue(0.5)) {
> +                  OpY = I->getOperand(1);
> +                  OpX = Op0;
> +                } else {
> +                  CFP = dyn_cast<ConstantFP>(I->getOperand(1));
> +                  if (CFP && CFP->isExactlyValue(0.5)) {
> +                    OpY = I->getOperand(0);
> +                    OpX = Op0;
> +                  }
> +                }
> +              }
> +            }
> +          }
> +        }
> +      }
> +    }
> +    // if pattern detected emit alternate sequence
> +    if (OpX && OpY) {
> +      Log2->setArgOperand(0, OpY);
> +      Value *FMulVal = Builder->CreateFMul(OpX, Log2);
> +      Instruction *FMul = dyn_cast<Instruction>(FMulVal);
> +      assert(FMul && "Must be instruction as Log2 is instruction");
> +      FMul->copyFastMathFlags(Log2);
> +      Instruction *FSub = BinaryOperator::CreateFSub(FMulVal, OpX);
> +      FSub->copyFastMathFlags(Log2);
> +      return FSub;
> +    }
> +  }
> +
>   return Changed ? &I : 0;
> }
> 
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list