[InstCombine] Add a new formula for SMIN.
authorSanjoy Das <sanjoy@playingwithpointers.com>
Thu, 30 Apr 2015 04:56:00 +0000 (04:56 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Thu, 30 Apr 2015 04:56:00 +0000 (04:56 +0000)
Summary:
After this change `MatchSelectPattern` recognizes the following form
of SMIN:

  Y >s C ? ~Y : ~C == ~Y <s ~C ? ~Y : ~C = SMIN(~Y, ~C)

Reviewers: majnemer

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D9352

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236202 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineSelect.cpp
test/Transforms/InstCombine/select.ll

index b28611f3604fc4b5a4b7d920b1c0bdfbfd270c96..6739314bc2490290b304da7a613a0436f5a7ba85 100644 (file)
@@ -86,6 +86,17 @@ MatchSelectPattern(Value *V, Value *&LHS, Value *&RHS) {
         return (CmpLHS == FalseVal) ? SPF_ABS : SPF_NABS;
       }
     }
+
+    // Y >s C ? ~Y : ~C == ~Y <s ~C ? ~Y : ~C = SMIN(~Y, ~C)
+    if (const auto *C2 = dyn_cast<ConstantInt>(FalseVal)) {
+      if (C1->getType() == C2->getType() && ~C1->getValue() == C2->getValue() &&
+          (match(TrueVal, m_Not(m_Specific(CmpLHS))) ||
+           match(CmpLHS, m_Not(m_Specific(TrueVal))))) {
+        LHS = TrueVal;
+        RHS = FalseVal;
+        return SPF_SMIN;
+      }
+    }
   }
 
   // TODO: (X > 4) ? X : 5   -->  (X >= 5) ? X : 5  -->  MAX(X, 5)
index ef122c92092da662ccabe18c3eb86425fdc93c5b..e4bc96cff1764d419ceb279090bc0a956b2a2c89 100644 (file)
@@ -1520,3 +1520,15 @@ define i32 @test_select_select1(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
   %s1 = select i1 %c1, i32 %r0, i32 %s0
   ret i32 %s1
 }
+
+define i32 @test_max_of_min(i32 %a) {
+; MAX(MIN(%a, -1), -1) == -1
+; CHECK-LABEL: @test_max_of_min(
+; CHECK: ret i32 -1
+  %not_a = xor i32 %a, -1
+  %c0 = icmp sgt i32 %a, 0
+  %s0 = select i1 %c0, i32 %not_a, i32 -1
+  %c1 = icmp sgt i32 %s0, -1
+  %s1 = select i1 %c1, i32 %s0, i32 -1
+  ret i32 %s1
+}