Add a small missed optimization: turn X == C ? X : Y into X == C ? C : Y. This
authorNick Lewycky <nicholas@mxc.ca>
Sun, 27 Mar 2011 07:30:57 +0000 (07:30 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Sun, 27 Mar 2011 07:30:57 +0000 (07:30 +0000)
removes one use of X which helps it pass the many hasOneUse() checks.

In my analysis, this turns up very often where X = A >>exact B and that can't be
simplified unless X has one use (except by increasing the lifetime of A which is
generally a performance loss).

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

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

index 8b9261b8fe00564eb3a6889344563860dacea456..50ea79f9b8c9e14ac01df1ede18c0b7a946c9d78 100644 (file)
@@ -424,6 +424,19 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
       return ReplaceInstUsesWith(SI, TrueVal);
     /// NOTE: if we wanted to, this is where to detect integer MIN/MAX
   }
+
+  if (isa<Constant>(CmpRHS)) {
+    if (CmpLHS == TrueVal && Pred == ICmpInst::ICMP_EQ) {
+      // Transform (X == C) ? X : Y -> (X == C) ? C : Y
+      SI.setOperand(1, CmpRHS);
+      Changed = true;
+    } else if (CmpLHS == FalseVal && Pred == ICmpInst::ICMP_NE) {
+      // Transform (X != C) ? Y : X -> (X != C) ? Y : C
+      SI.setOperand(2, CmpRHS);
+      Changed = true;
+    }
+  }
+
   return Changed ? &SI : 0;
 }
 
index e9981a523d5afbfb9a186f17967dd872e509722c..40237ae31058459bf9b8ff5d75244aba6876edd3 100644 (file)
@@ -724,3 +724,16 @@ define i32 @test53(i32 %x) nounwind {
 ; CHECK: select i1 %cmp
 ; CHECK: ret
 }
+
+define i32 @test54(i32 %X, i32 %Y) {
+  %A = ashr exact i32 %X, %Y
+  %B = icmp eq i32 %A, 0
+  %C = select i1 %B, i32 %A, i32 1
+  ret i32 %C
+; CHECK: @test54
+; CHECK-NOT: ashr
+; CHECK-NOT: select
+; CHECK: icmp ne i32 %X, 0
+; CHECK: zext 
+; CHECK: ret
+}