[llvm-commits] [llvm] r45158 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-12-18-AddSelCmpSub.ll

Christopher Lamb christopher.lamb at gmail.com
Tue Dec 18 12:08:07 PST 2007


On Dec 18, 2007, at 10:55 AM, Chris Lattner wrote:

>
> On Dec 18, 2007, at 1:34 AM, Christopher Lamb wrote:
>
>> Author: clamb
>> Date: Tue Dec 18 03:34:41 2007
>> New Revision: 45158
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=45158&view=rev
>> Log:
>> Fold certain additions through selects (and their compares) so as
>> to eliminate subtractions. This code is often produced by the SMAX
>> expansion in SCEV.
>>
>> This implements test/Transforms/InstCombine/2007-12-18- 
>> AddSelCmpSub.ll
>
> Nice! Thanks for tackling this,
>
>> --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
>> (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue
>> Dec 18 03:34:41 2007
>> @@ -2130,6 +2130,67 @@
>>        return new PtrToIntInst(I2, CI->getType());
>>      }
>>    }
>> +
>> +  // add (select (icmp 0 (sub m A)) X Y) A ->
>> +  //   add (select (icmp A m) X Y) A
>
> I'm not sure this is right: the idea is that this pushes the added
> value into the selected value, not into the compare:
>
>    add (select cond 0 (sub m A)) A -> (select cond A m)
>
> right?  We don't want to change the compare, because then a different
> value is picked.

I don't believe a different value is picked:

0 cond x - y
0 + y cond x - y + y
y cond x

However, (cmp 0 (sub m A)) -> (cmp A m) simply folds the subtract  
away and into the compare, it has nothing to do with the transform  
rooted at the add, so it probably should be done somewhere else if  
it's valuable.

>> +  //
>> +  // add (select X 0 (sub n A)) A ->
>> +  //  select X A n
>> +  {
>> +    SelectInst *SI = dyn_cast<SelectInst>(LHS);
>> +    Value *Other = RHS;
>> +    if (!SI) {
>> +      SI = dyn_cast<SelectInst>(RHS);
>> +      Other = LHS;
>> +    }
>> +    if (SI) {
>> +      Value *TV = SI->getTrueValue();
>> +      Value *FV = SI->getFalseValue();
>> +      Value *A;
>> +
>> +      // Can we fold the add into the argument of the compare?
>> +      Value *Cond = SI->getCondition();
>> +      if (ICmpInst *IC = dyn_cast<ICmpInst>(Cond)) {
>> +        Value *ICOp0 = IC->getOperand(0);
>> +        Value *ICOp1 = IC->getOperand(1);
>> +        ConstantInt *C3, *C4;
>> +
>> +        // Check both arguments of the compare for a matching
>> subtract.
>> +        if (match(ICOp0, m_ConstantInt(C3)) && C3->getValue() ==  
>> 0 &&
>> +            match(ICOp1, m_Sub(m_ConstantInt(C4), m_Value(A))) &&
>> +            A == Other) {
>> +          // We managed to fold the add into the RHS of the select
>> condition.
>> +          Cond = new ICmpInst(IC->getPredicate(), A, C4, "asis",  
>> SI);
>> +        } else if (match(ICOp1, m_ConstantInt(C3)) && C3->getValue
>> () == 0 &&
>> +            match(ICOp0, m_Sub(m_ConstantInt(C4), m_Value(A))) &&
>> +            A == Other) {
>> +          // We managed to fold the add into the LHS of the select
>> condition.
>> +          Cond = new ICmpInst(IC->getPredicate(), C4, A, "asis",  
>> SI);
>> +        }
>> +      }
>> +
>> +      // Can we fold the add into the argument of the select?
>> +      // We check both true and false select arguments for a
>> matching subtract.
>> +      ConstantInt *C1, *C2;
>> +      if (match(FV, m_ConstantInt(C1)) && C1->getValue() == 0 &&
>> +          match(TV, m_Sub(m_ConstantInt(C2), m_Value(A))) &&
>> +          A == Other) {
>> +        // We managed to fold the add into the true select value,
>> +        // picking up a simplified condition, if available.
>> +        return new SelectInst(Cond, C2, A, "adselsub");
>> +      } else if (match(TV, m_ConstantInt(C1)) && C1->getValue() ==
>> 0 &&
>> +                 match(FV, m_Sub(m_ConstantInt(C2), m_Value(A))) &&
>> +                 A == Other) {
>> +        // We managed to fold the add into the false select value,
>> +        // picking up a simplified condition, if available.
>> +        return new SelectInst(Cond, A, C2, "adselsub");
>> +      } else if (Cond != SI->getCondition()) {
>> +        // We only managed to fold the add into the select  
>> condition.
>> +        SI->setOperand(0, Cond);
>> +        Changed = true;
>> +      }
>> +    }
>> +  }
>>
>>    return Changed ? &I : 0;
>>  }
>>
>> Added: llvm/trunk/test/Transforms/InstCombine/2007-12-18-
>> AddSelCmpSub.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/
>> InstCombine/2007-12-18-AddSelCmpSub.ll?rev=45158&view=auto
>>
>> ===================================================================== 
>> =
>> ========
>> --- llvm/trunk/test/Transforms/InstCombine/2007-12-18-
>> AddSelCmpSub.ll (added)
>> +++ llvm/trunk/test/Transforms/InstCombine/2007-12-18-
>> AddSelCmpSub.ll Tue Dec 18 03:34:41 2007
>> @@ -0,0 +1,38 @@
>> +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {sub}
>> +
>> +define i32 @foo(i32 %a) {
>> +entry:
>> +        %tmp15 = sub i32 99, %a         ; <i32> [#uses=2]
>> +        %tmp16 = icmp slt i32 %tmp15, 0         ; <i1> [#uses=1]
>> +        %smax = select i1 %tmp16, i32 0, i32 %tmp15             ;
>> <i32> [#uses=1]
>> +        %tmp12 = add i32 %smax, %a              ; <i32> [#uses=1]
>> +        %tmp13 = add i32 %tmp12, 1              ; <i32> [#uses=1]
>> +        ret i32 %tmp13
>> +}
>> +
>> +define i32 @bar(i32 %a) {
>> +entry:
>> +        %tmp15 = sub i32 99, %a         ; <i32> [#uses=2]
>> +        %tmp16 = icmp slt i32 %tmp15, 0         ; <i1> [#uses=1]
>> +        %smax = select i1 %tmp16, i32 0, i32 %tmp15             ;
>> <i32> [#uses=1]
>> +        %tmp12 = add i32 %smax, %a              ; <i32> [#uses=1]
>> +        ret i32 %tmp12
>> +}
>> +
>> +define i32 @baz(i32 %a) {
>> +entry:
>> +        %tmp15 = sub i32 99, %a         ; <i32> [#uses=1]
>> +        %tmp16 = icmp slt i32 %tmp15, 0         ; <i1> [#uses=1]
>> +        %smax = select i1 %tmp16, i32 0, i32 42             ;
>> <i32> [#uses=1]
>> +        %tmp12 = add i32 %smax, %a              ; <i32> [#uses=1]
>> +        ret i32 %tmp12
>> +}
>> +
>> +define i32 @fun(i32 %a) {
>> +entry:
>> +        %tmp15 = sub i32 99, %a         ; <i32> [#uses=1]
>> +        %tmp16 = icmp slt i32 %a, 0         ; <i1> [#uses=1]
>> +        %smax = select i1 %tmp16, i32 0, i32 %tmp15             ;
>> <i32> [#uses=1]
>> +        %tmp12 = add i32 %smax, %a              ; <i32> [#uses=1]
>> +        ret i32 %tmp12
>> +}
>> \ No newline at end of file
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

--
Christopher Lamb



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20071218/88b4f6cb/attachment.html>


More information about the llvm-commits mailing list