diff options
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineSelect.cpp | 13 | ||||
-rw-r--r-- | test/Transforms/InstCombine/select.ll | 13 |
2 files changed, 26 insertions, 0 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineSelect.cpp b/lib/Transforms/InstCombine/InstCombineSelect.cpp index 8b9261b..50ea79f 100644 --- a/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -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; } diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index e9981a5..40237ae 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -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 +} |