[llvm-commits] [llvm] r108378 - in /llvm/trunk/lib/Transforms/InstCombine: InstCombineAndOrXor.cpp InstCombineSelect.cpp

Eli Friedman eli.friedman at gmail.com
Wed Jul 14 16:47:26 PDT 2010


On Wed, Jul 14, 2010 at 4:33 PM, Owen Anderson <resistor at mac.com> wrote:
> Author: resistor
> Date: Wed Jul 14 18:33:51 2010
> New Revision: 108378
>
> URL: http://llvm.org/viewvc/llvm-project?rev=108378&view=rev
> Log:
> Add instcombine transforms to optimize tests of multiple bits of the same value into a single larger comparison.
>
> Modified:
>    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
>    llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp

Tests?

> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=108378&r1=108377&r2=108378&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Wed Jul 14 18:33:51 2010
> @@ -699,6 +699,31 @@
>     SI.setOperand(2, TrueVal);
>     return &SI;
>   }
> +
> +  // select (or (A == 0) (B == 0)) T, F--> select (and (A != 0) (B != 0)) F, T
> +  // Note: This is a canonicalization rather than an optimization, and is used
> +  // to expose opportunities to other instcombine transforms.
> +  Instruction* CondInst = dyn_cast<Instruction>(CondVal);
> +  if (CondInst && CondInst->getOpcode() == Instruction::Or) {
> +    ICmpInst *LHSCmp = dyn_cast<ICmpInst>(CondInst->getOperand(0));
> +    ICmpInst *RHSCmp = dyn_cast<ICmpInst>(CondInst->getOperand(1));
> +    if (LHSCmp && LHSCmp->getPredicate() == ICmpInst::ICMP_EQ &&
> +        RHSCmp && RHSCmp->getPredicate() == ICmpInst::ICMP_EQ) {
> +      ConstantInt* C1 = dyn_cast<ConstantInt>(LHSCmp->getOperand(1));
> +      ConstantInt* C2 = dyn_cast<ConstantInt>(RHSCmp->getOperand(1));
> +      if (C1 && C1->isZero() && C2 && C2->isZero()) {
> +        LHSCmp->setPredicate(ICmpInst::ICMP_NE);
> +        RHSCmp->setPredicate(ICmpInst::ICMP_NE);
> +        Value *And =
> +          InsertNewInstBefore(BinaryOperator::CreateAnd(LHSCmp, RHSCmp,
> +                                             "and."+CondVal->getName()), SI);
> +        SI.setOperand(0, And);
> +        SI.setOperand(1, FalseVal);
> +        SI.setOperand(2, TrueVal);
> +        return &SI;
> +      }
> +    }
> +  }

Is this missing checks that the or and cmp instructions only have one use?

-Eli




More information about the llvm-commits mailing list