Fix a README item: when doing a comparison with the result
authorDuncan Sands <baldrick@free.fr>
Sun, 7 Nov 2010 16:12:23 +0000 (16:12 +0000)
committerDuncan Sands <baldrick@free.fr>
Sun, 7 Nov 2010 16:12:23 +0000 (16:12 +0000)
of a select instruction, see if doing the compare with the
true and false values of the select gives the same result.
If so, that can be used as the value of the comparison.

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

lib/Analysis/InstructionSimplify.cpp
lib/Target/README.txt
test/Transforms/InstCombine/select.ll

index b49b4d0c6aba31152f82f0beecd7655b57b3c82d..1955802cc6ed360e5c164d679660e67bfdafea6c 100644 (file)
@@ -252,8 +252,27 @@ Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
       break;
     }
   }
-  
-  
+
+  // If the comparison is with the result of a select instruction, check whether
+  // comparing with either branch of the select always yields the same value.
+  if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS)) {
+    // Make sure the select is on the LHS.
+    if (!isa<SelectInst>(LHS)) {
+      std::swap(LHS, RHS);
+      Pred = CmpInst::getSwappedPredicate(Pred);
+    }
+    SelectInst *SI = cast<SelectInst>(LHS);
+    // Now that we have "icmp select(cond, TV, FV), RHS", analyse it.
+    // Does "icmp TV, RHS" simplify?
+    if (Value *TCmp = SimplifyICmpInst(Pred, SI->getTrueValue(), RHS, TD))
+      // It does!  Does "icmp FV, RHS" simplify?
+      if (Value *FCmp = SimplifyICmpInst(Pred, SI->getFalseValue(), RHS, TD))
+        // It does!  If they simplified to the same value, then use it as the
+        // result of the original comparison.
+        if (TCmp == FCmp)
+          return TCmp;
+  }
+
   return 0;
 }
 
index 55c08173d200ba2fe67ddd372bb8c64fd463e441..e63df536ae076c78a1288a77606060f68a50b74a 100644 (file)
@@ -1963,15 +1963,3 @@ bb3:            ; preds = %entry
         ret i32 %b
 }
 //===---------------------------------------------------------------------===//
-We should fold this code into "ret i1 false" since neither %zero nor %one can
-ever be null pointers.
-
-define i1 @foo(i1 %cond) {
-  %zero = alloca i32
-  %one = alloca i32
-
-  %ptr = select i1 %cond, i32* %zero, i32* %one
-  %isnull = icmp eq i32* %ptr, null
-  ret i1 %isnull
-}
-//===---------------------------------------------------------------------===//
index 246a7bc59783eee12d2e830c67c5dec344d9e081..c641339cbb6db7d77407736504d6d31f319648d4 100644 (file)
@@ -470,3 +470,13 @@ define i32 @test37(i32 %x) {
 ; CHECK: or i32 {{.*}}, 1
 ; CHECK: ret
 }
+
+define i1 @test38(i1 %cond) {
+  %zero = alloca i32
+  %one = alloca i32
+  %ptr = select i1 %cond, i32* %zero, i32* %one
+  %isnull = icmp eq i32* %ptr, null
+  ret i1 %isnull
+; CHECK: @test38
+; CHECK: ret i1 false
+}