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. -Chris > + // > + // 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@cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits