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

--
Christopher Lamb



_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to