aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/InstCombine
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/InstCombine')
-rw-r--r--llvm/test/Transforms/InstCombine/binop-phi-operands.ll5
-rw-r--r--llvm/test/Transforms/InstCombine/binop-select.ll187
-rw-r--r--llvm/test/Transforms/InstCombine/dont-distribute-phi.ll10
-rw-r--r--llvm/test/Transforms/InstCombine/fmul.ll4
-rw-r--r--llvm/test/Transforms/InstCombine/free-inversion.ll4
-rw-r--r--llvm/test/Transforms/InstCombine/or-select-zero-icmp.ll169
-rw-r--r--llvm/test/Transforms/InstCombine/recurrence.ll4
-rw-r--r--llvm/test/Transforms/InstCombine/sub-gep.ll3
8 files changed, 368 insertions, 18 deletions
diff --git a/llvm/test/Transforms/InstCombine/binop-phi-operands.ll b/llvm/test/Transforms/InstCombine/binop-phi-operands.ll
index 9e04983..f0d4ad7 100644
--- a/llvm/test/Transforms/InstCombine/binop-phi-operands.ll
+++ b/llvm/test/Transforms/InstCombine/binop-phi-operands.ll
@@ -653,12 +653,11 @@ define i8 @mul_const_incoming0_speculatable(i1 %b, i8 %x, i8 %y) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
; CHECK: if:
+; CHECK-NEXT: [[TMP0:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br label [[THEN]]
; CHECK: then:
-; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[ENTRY:%.*]] ], [ [[X:%.*]], [[IF]] ]
-; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 17, [[ENTRY]] ], [ [[Y:%.*]], [[IF]] ]
+; CHECK-NEXT: [[R:%.*]] = phi i8 [ -54, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]
; CHECK-NEXT: call void @sideeffect()
-; CHECK-NEXT: [[R:%.*]] = mul i8 [[P0]], [[P1]]
; CHECK-NEXT: ret i8 [[R]]
;
entry:
diff --git a/llvm/test/Transforms/InstCombine/binop-select.ll b/llvm/test/Transforms/InstCombine/binop-select.ll
index 25f624e..fe1ec90 100644
--- a/llvm/test/Transforms/InstCombine/binop-select.ll
+++ b/llvm/test/Transforms/InstCombine/binop-select.ll
@@ -335,7 +335,7 @@ define i32 @sub_sel_op1_use(i1 %b) {
define float @fadd_sel_op0(i1 %b, float %x) {
; CHECK-LABEL: @fadd_sel_op0(
-; CHECK-NEXT: [[R:%.*]] = select nnan i1 [[B:%.*]], float 0xFFF0000000000000, float 0x7FF0000000000000
+; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], float 0xFFF0000000000000, float 0x7FF0000000000000
; CHECK-NEXT: ret float [[R]]
;
%s = select i1 %b, float 0xFFF0000000000000, float 0x7FF0000000000000
@@ -403,3 +403,188 @@ define i32 @ashr_sel_op1_use(i1 %b) {
%r = ashr i32 -2, %s
ret i32 %r
}
+
+define i8 @commonArgWithOr0(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithOr0(
+; CHECK-NEXT: [[V0:%.*]] = zext i1 [[ARG0:%.*]] to i8
+; CHECK-NEXT: [[V1:%.*]] = select i1 [[ARG0]], i8 0, i8 8
+; CHECK-NEXT: [[V2:%.*]] = or disjoint i8 [[V1]], [[V0]]
+; CHECK-NEXT: [[V3:%.*]] = or disjoint i8 [[V2]], 16
+; CHECK-NEXT: ret i8 [[V3]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 0, i8 8
+ %v2 = or i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithOr1(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithOr1(
+; CHECK-NEXT: [[V3:%.*]] = select i1 [[ARG0:%.*]], i8 17, i8 23
+; CHECK-NEXT: ret i8 [[V3]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 1, i8 7
+ %v2 = or i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithOr2(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithOr2(
+; CHECK-NEXT: [[V0:%.*]] = zext i1 [[ARG0:%.*]] to i8
+; CHECK-NEXT: [[V1:%.*]] = select i1 [[ARG0]], i8 5, i8 42
+; CHECK-NEXT: [[V2:%.*]] = or i8 [[V1]], [[V0]]
+; CHECK-NEXT: [[V3:%.*]] = or disjoint i8 [[V2]], 16
+; CHECK-NEXT: ret i8 [[V3]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 21, i8 42
+ %v2 = or i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithAnd0(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithAnd0(
+; CHECK-NEXT: ret i8 16
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 0, i8 8
+ %v2 = and i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithAnd1(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithAnd1(
+; CHECK-NEXT: ret i8 16
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 8, i8 1
+ %v2 = and i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithAnd2(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithAnd2(
+; CHECK-NEXT: [[V2:%.*]] = zext i1 [[ARG0:%.*]] to i8
+; CHECK-NEXT: [[V3:%.*]] = or disjoint i8 [[V2]], 16
+; CHECK-NEXT: ret i8 [[V3]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 1, i8 7
+ %v2 = and i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithAnd3(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithAnd3(
+; CHECK-NEXT: [[V2:%.*]] = zext i1 [[ARG0:%.*]] to i8
+; CHECK-NEXT: [[V3:%.*]] = or disjoint i8 [[V2]], 16
+; CHECK-NEXT: ret i8 [[V3]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 21, i8 42
+ %v2 = and i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithXor0(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithXor0(
+; CHECK-NEXT: [[V0:%.*]] = zext i1 [[ARG0:%.*]] to i8
+; CHECK-NEXT: [[V1:%.*]] = select i1 [[ARG0]], i8 0, i8 8
+; CHECK-NEXT: [[V2:%.*]] = or disjoint i8 [[V1]], [[V0]]
+; CHECK-NEXT: [[V3:%.*]] = or disjoint i8 [[V2]], 16
+; CHECK-NEXT: ret i8 [[V3]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 0, i8 8
+ %v2 = xor i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithXor1(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithXor1(
+; CHECK-NEXT: [[V0:%.*]] = zext i1 [[ARG0:%.*]] to i8
+; CHECK-NEXT: [[V1:%.*]] = select i1 [[ARG0]], i8 9, i8 1
+; CHECK-NEXT: [[V2:%.*]] = xor i8 [[V1]], [[V0]]
+; CHECK-NEXT: ret i8 [[V2]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 9, i8 1
+ %v2 = xor i8 %v1, %v0
+ ret i8 %v2
+}
+
+define i8 @commonArgWithXor2(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithXor2(
+; CHECK-NEXT: [[V0:%.*]] = zext i1 [[ARG0:%.*]] to i8
+; CHECK-NEXT: [[V1:%.*]] = select i1 [[ARG0]], i8 1, i8 7
+; CHECK-NEXT: [[V2:%.*]] = xor i8 [[V1]], [[V0]]
+; CHECK-NEXT: [[V3:%.*]] = or disjoint i8 [[V2]], 16
+; CHECK-NEXT: ret i8 [[V3]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 1, i8 7
+ %v2 = xor i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithXor3(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithXor3(
+; CHECK-NEXT: [[V0:%.*]] = zext i1 [[ARG0:%.*]] to i8
+; CHECK-NEXT: [[V1:%.*]] = select i1 [[ARG0]], i8 5, i8 45
+; CHECK-NEXT: [[V2:%.*]] = xor i8 [[V1]], [[V0]]
+; CHECK-NEXT: [[V3:%.*]] = or disjoint i8 [[V2]], 16
+; CHECK-NEXT: ret i8 [[V3]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 21, i8 45
+ %v2 = xor i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i8 @commonArgWithAdd0(i1 %arg0) {
+; CHECK-LABEL: @commonArgWithAdd0(
+; CHECK-NEXT: [[V3:%.*]] = select i1 [[ARG0:%.*]], i8 22, i8 61
+; CHECK-NEXT: ret i8 [[V3]]
+;
+ %v0 = zext i1 %arg0 to i8
+ %v1 = select i1 %arg0, i8 21, i8 45
+ %v2 = add i8 %v1, %v0
+ %v3 = or i8 %v2, 16
+ ret i8 %v3
+}
+
+define i32 @OrSelectIcmpZero(i32 %a, i32 %b) {
+; CHECK-LABEL: @OrSelectIcmpZero(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
+; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 [[A]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %cmp = icmp eq i32 %a, 0
+ %sel = select i1 %cmp, i32 %b, i32 0
+ %or = or i32 %sel, %a
+ ret i32 %or
+}
+
+define i32 @OrSelectIcmpNonZero(i32 %a, i32 %b) {
+; CHECK-LABEL: @OrSelectIcmpNonZero(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 42
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL]], [[A]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %cmp = icmp eq i32 %a, 0
+ %sel = select i1 %cmp, i32 %b, i32 42
+ %or = or i32 %sel, %a
+ ret i32 %or
+}
diff --git a/llvm/test/Transforms/InstCombine/dont-distribute-phi.ll b/llvm/test/Transforms/InstCombine/dont-distribute-phi.ll
index 45e47d8..5e90d4b 100644
--- a/llvm/test/Transforms/InstCombine/dont-distribute-phi.ll
+++ b/llvm/test/Transforms/InstCombine/dont-distribute-phi.ll
@@ -7,7 +7,7 @@
define zeroext i1 @foo(i32 %arg) {
; CHECK-LABEL: @foo(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[ARG:%.*]], 37
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[ARG:%.*]], 37
; CHECK-NEXT: br i1 [[CMP1]], label [[BB_ELSE:%.*]], label [[BB_THEN:%.*]]
; CHECK: bb_then:
; CHECK-NEXT: call void @bar()
@@ -16,8 +16,7 @@ define zeroext i1 @foo(i32 %arg) {
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[ARG]], 17
; CHECK-NEXT: br label [[BB_EXIT]]
; CHECK: bb_exit:
-; CHECK-NEXT: [[PHI1:%.*]] = phi i1 [ [[CMP2]], [[BB_ELSE]] ], [ undef, [[BB_THEN]] ]
-; CHECK-NEXT: [[AND1:%.*]] = and i1 [[PHI1]], [[CMP1]]
+; CHECK-NEXT: [[AND1:%.*]] = phi i1 [ [[CMP2]], [[BB_THEN]] ], [ false, [[BB_ELSE]] ]
; CHECK-NEXT: ret i1 [[AND1]]
;
@@ -43,7 +42,7 @@ bb_exit:
define zeroext i1 @foo_logical(i32 %arg) {
; CHECK-LABEL: @foo_logical(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[ARG:%.*]], 37
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[ARG:%.*]], 37
; CHECK-NEXT: br i1 [[CMP1]], label [[BB_ELSE:%.*]], label [[BB_THEN:%.*]]
; CHECK: bb_then:
; CHECK-NEXT: call void @bar()
@@ -52,8 +51,7 @@ define zeroext i1 @foo_logical(i32 %arg) {
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[ARG]], 17
; CHECK-NEXT: br label [[BB_EXIT]]
; CHECK: bb_exit:
-; CHECK-NEXT: [[PHI1:%.*]] = phi i1 [ [[CMP2]], [[BB_ELSE]] ], [ undef, [[BB_THEN]] ]
-; CHECK-NEXT: [[AND1:%.*]] = and i1 [[PHI1]], [[CMP1]]
+; CHECK-NEXT: [[AND1:%.*]] = phi i1 [ [[CMP2]], [[BB_THEN]] ], [ false, [[BB_ELSE]] ]
; CHECK-NEXT: ret i1 [[AND1]]
;
diff --git a/llvm/test/Transforms/InstCombine/fmul.ll b/llvm/test/Transforms/InstCombine/fmul.ll
index cd4a8e3..3cbf709 100644
--- a/llvm/test/Transforms/InstCombine/fmul.ll
+++ b/llvm/test/Transforms/InstCombine/fmul.ll
@@ -1222,7 +1222,7 @@ define <2 x double> @negate_if_true_wrong_constant(<2 x double> %px, i1 %cond) {
; X *fast (C ? 1.0 : 0.0) -> C ? X : 0.0
define float @fmul_select(float %x, i1 %c) {
; CHECK-LABEL: @fmul_select(
-; CHECK-NEXT: [[MUL:%.*]] = select fast i1 [[C:%.*]], float [[X:%.*]], float 0.000000e+00
+; CHECK-NEXT: [[MUL:%.*]] = select i1 [[C:%.*]], float [[X:%.*]], float 0.000000e+00
; CHECK-NEXT: ret float [[MUL]]
;
%sel = select i1 %c, float 1.0, float 0.0
@@ -1233,7 +1233,7 @@ define float @fmul_select(float %x, i1 %c) {
; X *fast (C ? 1.0 : 0.0) -> C ? X : 0.0
define <2 x float> @fmul_select_vec(<2 x float> %x, i1 %c) {
; CHECK-LABEL: @fmul_select_vec(
-; CHECK-NEXT: [[MUL:%.*]] = select fast i1 [[C:%.*]], <2 x float> [[X:%.*]], <2 x float> zeroinitializer
+; CHECK-NEXT: [[MUL:%.*]] = select i1 [[C:%.*]], <2 x float> [[X:%.*]], <2 x float> zeroinitializer
; CHECK-NEXT: ret <2 x float> [[MUL]]
;
%sel = select i1 %c, <2 x float> <float 1.0, float 1.0>, <2 x float> zeroinitializer
diff --git a/llvm/test/Transforms/InstCombine/free-inversion.ll b/llvm/test/Transforms/InstCombine/free-inversion.ll
index 4b69a5e77..2e8e75c 100644
--- a/llvm/test/Transforms/InstCombine/free-inversion.ll
+++ b/llvm/test/Transforms/InstCombine/free-inversion.ll
@@ -563,10 +563,10 @@ define i1 @test_inv_free(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {
; CHECK: b2:
; CHECK-NEXT: br label [[EXIT]]
; CHECK: b3:
+; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[C3:%.*]], [[C4:%.*]]
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
-; CHECK-NEXT: [[VAL_NOT:%.*]] = phi i1 [ false, [[B1]] ], [ true, [[B2]] ], [ [[C3:%.*]], [[B3]] ]
-; CHECK-NEXT: [[COND_NOT:%.*]] = and i1 [[VAL_NOT]], [[C4:%.*]]
+; CHECK-NEXT: [[COND_NOT:%.*]] = phi i1 [ false, [[B1]] ], [ [[C4]], [[B2]] ], [ [[TMP0]], [[B3]] ]
; CHECK-NEXT: br i1 [[COND_NOT]], label [[B5:%.*]], label [[B4:%.*]]
; CHECK: b4:
; CHECK-NEXT: ret i1 true
diff --git a/llvm/test/Transforms/InstCombine/or-select-zero-icmp.ll b/llvm/test/Transforms/InstCombine/or-select-zero-icmp.ll
new file mode 100644
index 0000000..a3b21cc
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/or-select-zero-icmp.ll
@@ -0,0 +1,169 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; Basic functional test
+define i32 @basic(i32 %a, i32 %b) {
+; CHECK-LABEL: @basic(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 [[A]]
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %cmp = icmp eq i32 %a, 0
+ %sel = select i1 %cmp, i32 %b, i32 0
+ %or = or i32 %sel, %a
+ ret i32 %or
+}
+
+; Operand order swap test
+define i32 @swap_operand_order(i32 %x, i32 %y) {
+; CHECK-LABEL: @swap_operand_order(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[Y:%.*]], i32 0
+; CHECK-NEXT: [[RES:%.*]] = or i32 [[X]], [[SEL]]
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %cmp = icmp eq i32 %x, 0
+ %sel = select i1 %cmp, i32 %y, i32 0
+ %or = or i32 %x, %sel
+ ret i32 %or
+}
+
+; Negative test: Non-zero false value in select
+define i32 @negative_non_zero_false_val(i32 %a, i32 %b) {
+; CHECK-LABEL: @negative_non_zero_false_val(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 1
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL]], [[A]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %cmp = icmp eq i32 %a, 0
+ %sel = select i1 %cmp, i32 %b, i32 1
+ %or = or i32 %sel, %a
+ ret i32 %or
+}
+
+; Negative test: Incorrect comparison predicate (NE)
+define i32 @negative_wrong_predicate(i32 %a, i32 %b) {
+; CHECK-LABEL: @negative_wrong_predicate(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
+; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP]], i32 0, i32 [[TMP1:%.*]]
+; CHECK-NEXT: [[OR1:%.*]] = or i32 [[OR]], [[A]]
+; CHECK-NEXT: ret i32 [[OR1]]
+;
+ %cmp = icmp ne i32 %a, 0
+ %sel = select i1 %cmp, i32 %b, i32 0
+ %or = or i32 %sel, %a
+ ret i32 %or
+}
+
+; Comparison direction swap test (0 == X)
+define i32 @cmp_swapped(i32 %x, i32 %y) {
+; CHECK-LABEL: @cmp_swapped(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[Y:%.*]], i32 0
+; CHECK-NEXT: [[RES:%.*]] = or i32 [[X]], [[SEL]]
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %cmp = icmp eq i32 0, %x
+ %sel = select i1 %cmp, i32 %y, i32 0
+ %or = or i32 %x, %sel
+ ret i32 %or
+}
+
+; Complex expression test
+define i32 @complex_expression(i32 %a, i32 %b) {
+; CHECK-LABEL: @complex_expression(
+; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 0
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 [[X]]
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %x = add i32 %a, 1
+ %cmp = icmp eq i32 %x, 0
+ %sel = select i1 %cmp, i32 %b, i32 0
+ %or = or i32 %sel, %x
+ ret i32 %or
+}
+
+; zext test
+define i32 @zext_cond(i8 %a, i32 %b) {
+; CHECK-LABEL: @zext_cond(
+; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i32
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 0
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 0
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL]], [[Z]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %z = zext i8 %a to i32
+ %cmp = icmp eq i8 %a, 0
+ %sel = select i1 %cmp, i32 %b, i32 0
+ %or = or i32 %sel, %z
+ ret i32 %or
+}
+
+; sext test
+define i32 @sext_cond(i8 %a, i32 %b) {
+; CHECK-LABEL: @sext_cond(
+; CHECK-NEXT: [[S:%.*]] = sext i8 [[A:%.*]] to i32
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 0
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 0
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL]], [[S]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %s = sext i8 %a to i32
+ %cmp = icmp eq i8 %a, 0
+ %sel = select i1 %cmp, i32 %b, i32 0
+ %or = or i32 %sel, %s
+ ret i32 %or
+}
+
+; Vector type test
+define <2 x i32> @vector_type(<2 x i32> %a, <2 x i32> %b) {
+; CHECK-LABEL: @vector_type(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], zeroinitializer
+; CHECK-NEXT: [[RES:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[B:%.*]], <2 x i32> [[A]]
+; CHECK-NEXT: ret <2 x i32> [[RES]]
+;
+ %cmp = icmp eq <2 x i32> %a, zeroinitializer
+ %sel = select <2 x i1> %cmp, <2 x i32> %b, <2 x i32> zeroinitializer
+ %or = or <2 x i32> %sel, %a
+ ret <2 x i32> %or
+}
+
+; Pointer type test (should not trigger optimization)
+define ptr @pointer_type(ptr %p, ptr %q) {
+; CHECK-LABEL: @pointer_type(
+; CHECK-NEXT: [[A:%.*]] = ptrtoint ptr [[P:%.*]] to i64
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P]], null
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], ptr [[Q:%.*]], ptr null
+; CHECK-NEXT: [[SEL_INT:%.*]] = ptrtoint ptr [[SEL]] to i64
+; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[SEL_INT]]
+; CHECK-NEXT: [[RET:%.*]] = inttoptr i64 [[OR]] to ptr
+; CHECK-NEXT: ret ptr [[RET]]
+;
+ %a = ptrtoint ptr %p to i64
+ %cmp = icmp eq i64 %a, 0
+ %sel = select i1 %cmp, ptr %q, ptr null
+ %sel_int = ptrtoint ptr %sel to i64
+ %or_val = or i64 %a, %sel_int
+ %ret = inttoptr i64 %or_val to ptr
+ ret ptr %ret
+}
+
+; Multi-use test (should not trigger optimization)
+define i32 @multi_use_test(i32 %x, i32 %m) {
+; CHECK-LABEL: @multi_use_test(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[M:%.*]], i32 0
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL]], [[X]]
+; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SEL]], [[X]]
+; CHECK-NEXT: [[O2:%.*]] = sub i32 [[OR]], [[ADD]]
+; CHECK-NEXT: ret i32 [[O2]]
+;
+ %cmp = icmp eq i32 %x, 0
+ %sel = select i1 %cmp, i32 %m, i32 0
+ %or = or i32 %sel, %x
+ %add = add i32 %sel, %x
+ %res = sub i32 %or, %add
+ ret i32 %res
+}
diff --git a/llvm/test/Transforms/InstCombine/recurrence.ll b/llvm/test/Transforms/InstCombine/recurrence.ll
index f75e0d4..643e7efc 100644
--- a/llvm/test/Transforms/InstCombine/recurrence.ll
+++ b/llvm/test/Transforms/InstCombine/recurrence.ll
@@ -24,9 +24,9 @@ loop: ; preds = %loop, %entry
define i64 @test_or2(i64 %a, i64 %b) {
; CHECK-LABEL: @test_or2(
; CHECK-NEXT: entry:
+; CHECK-NEXT: [[IV_NEXT:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[IV_NEXT:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: tail call void @use(i64 [[IV_NEXT]])
; CHECK-NEXT: br label [[LOOP]]
;
@@ -104,9 +104,9 @@ loop: ; preds = %loop, %entry
define i64 @test_and2(i64 %a, i64 %b) {
; CHECK-LABEL: @test_and2(
; CHECK-NEXT: entry:
+; CHECK-NEXT: [[IV_NEXT:%.*]] = and i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[IV_NEXT:%.*]] = and i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: tail call void @use(i64 [[IV_NEXT]])
; CHECK-NEXT: br label [[LOOP]]
;
diff --git a/llvm/test/Transforms/InstCombine/sub-gep.ll b/llvm/test/Transforms/InstCombine/sub-gep.ll
index ee70137..01da63f 100644
--- a/llvm/test/Transforms/InstCombine/sub-gep.ll
+++ b/llvm/test/Transforms/InstCombine/sub-gep.ll
@@ -858,8 +858,7 @@ define i1 @_gep_phi2(ptr %str1, i64 %val2) {
; CHECK: while.end.i:
; CHECK-NEXT: br label [[_Z3FOOPKC_EXIT]]
; CHECK: _Z3fooPKc.exit:
-; CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i64 [ 1, [[WHILE_END_I]] ], [ 0, [[LOR_LHS_FALSE_I]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[TMP2:%.*]] = or i64 [[RETVAL_0_I]], [[VAL2:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ 1, [[WHILE_END_I]] ], [ [[VAL2:%.*]], [[LOR_LHS_FALSE_I]] ], [ [[VAL2]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[TMP2]], 0
; CHECK-NEXT: ret i1 [[TOBOOL]]
;