xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll (revision 0f0c0c36e3e90b4cb04004ed9c930f3863a36422)
1175d68ddSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2175d68ddSFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3175d68ddSFlorian Hahn
4175d68ddSFlorian Hahndefine i1 @test_second_and_condition_implied_by_first(i8 %x) {
5175d68ddSFlorian Hahn; CHECK-LABEL: @test_second_and_condition_implied_by_first(
6175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
7175d68ddSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
8175d68ddSFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
90ad6879aSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], true
10175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
11175d68ddSFlorian Hahn; CHECK:       then:
12175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 false
13175d68ddSFlorian Hahn; CHECK:       else:
14175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 true
15175d68ddSFlorian Hahn;
16175d68ddSFlorian Hahnentry:
17175d68ddSFlorian Hahn  %c.1 = icmp ugt i8 %x, 10
18175d68ddSFlorian Hahn  %t.1 = icmp ugt i8 %x, 5
19175d68ddSFlorian Hahn  %and = and i1 %c.1, %t.1
20175d68ddSFlorian Hahn  br i1 %and, label %then, label %else
21175d68ddSFlorian Hahn
22175d68ddSFlorian Hahnthen:
23175d68ddSFlorian Hahn  ret i1 0
24175d68ddSFlorian Hahn
25175d68ddSFlorian Hahnelse:
26175d68ddSFlorian Hahn  ret i1 1
27175d68ddSFlorian Hahn}
28175d68ddSFlorian Hahn
29c014454fSFlorian Hahndefine i1 @test_first_and_condition_implied_by_second_ops(i8 %x) {
30c014454fSFlorian Hahn; CHECK-LABEL: @test_first_and_condition_implied_by_second_ops(
31c014454fSFlorian Hahn; CHECK-NEXT:  entry:
32c014454fSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
33c014454fSFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
347cf499c6SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[C_1]]
35c014454fSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
36c014454fSFlorian Hahn; CHECK:       then:
37c014454fSFlorian Hahn; CHECK-NEXT:    ret i1 false
38c014454fSFlorian Hahn; CHECK:       else:
39c014454fSFlorian Hahn; CHECK-NEXT:    ret i1 true
40c014454fSFlorian Hahn;
41c014454fSFlorian Hahnentry:
42c014454fSFlorian Hahn  %c.1 = icmp ugt i8 %x, 10
43c014454fSFlorian Hahn  %t.1 = icmp ugt i8 %x, 5
44c014454fSFlorian Hahn  %and = and i1 %t.1, %c.1
45c014454fSFlorian Hahn  br i1 %and, label %then, label %else
46c014454fSFlorian Hahn
47c014454fSFlorian Hahnthen:
48c014454fSFlorian Hahn  ret i1 0
49c014454fSFlorian Hahn
50c014454fSFlorian Hahnelse:
51c014454fSFlorian Hahn  ret i1 1
52c014454fSFlorian Hahn}
53c014454fSFlorian Hahn
540332f2c5SFlorian Hahndefine i1 @test_second_and_condition_implied_by_first_select_form(i8 %x) {
550332f2c5SFlorian Hahn; CHECK-LABEL: @test_second_and_condition_implied_by_first_select_form(
560332f2c5SFlorian Hahn; CHECK-NEXT:  entry:
570332f2c5SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
580332f2c5SFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
590ad6879aSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_1]], i1 true, i1 false
600332f2c5SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
610332f2c5SFlorian Hahn; CHECK:       then:
620332f2c5SFlorian Hahn; CHECK-NEXT:    ret i1 false
630332f2c5SFlorian Hahn; CHECK:       else:
640332f2c5SFlorian Hahn; CHECK-NEXT:    ret i1 true
650332f2c5SFlorian Hahn;
660332f2c5SFlorian Hahnentry:
670332f2c5SFlorian Hahn  %c.1 = icmp ugt i8 %x, 10
680332f2c5SFlorian Hahn  %t.1 = icmp ugt i8 %x, 5
690332f2c5SFlorian Hahn  %and = select i1 %c.1, i1 %t.1, i1 false
700332f2c5SFlorian Hahn  br i1 %and, label %then, label %else
710332f2c5SFlorian Hahn
720332f2c5SFlorian Hahnthen:
730332f2c5SFlorian Hahn  ret i1 0
740332f2c5SFlorian Hahn
750332f2c5SFlorian Hahnelse:
760332f2c5SFlorian Hahn  ret i1 1
770332f2c5SFlorian Hahn}
780332f2c5SFlorian Hahn
79c014454fSFlorian Hahndefine i1 @test_first_and_condition_implied_by_second_select_form(i8 %x) {
80c014454fSFlorian Hahn; CHECK-LABEL: @test_first_and_condition_implied_by_second_select_form(
81c014454fSFlorian Hahn; CHECK-NEXT:  entry:
82c014454fSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
83c014454fSFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
84c014454fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = select i1 [[T_1]], i1 [[C_1]], i1 false
85c014454fSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
86c014454fSFlorian Hahn; CHECK:       then:
87c014454fSFlorian Hahn; CHECK-NEXT:    ret i1 false
88c014454fSFlorian Hahn; CHECK:       else:
89c014454fSFlorian Hahn; CHECK-NEXT:    ret i1 true
90c014454fSFlorian Hahn;
91c014454fSFlorian Hahnentry:
92c014454fSFlorian Hahn  %c.1 = icmp ugt i8 %x, 10
93c014454fSFlorian Hahn  %t.1 = icmp ugt i8 %x, 5
94c014454fSFlorian Hahn  %and = select i1 %t.1, i1 %c.1, i1 false
95c014454fSFlorian Hahn  br i1 %and, label %then, label %else
96c014454fSFlorian Hahn
97c014454fSFlorian Hahnthen:
98c014454fSFlorian Hahn  ret i1 0
99c014454fSFlorian Hahn
100c014454fSFlorian Hahnelse:
101c014454fSFlorian Hahn  ret i1 1
102c014454fSFlorian Hahn}
103c014454fSFlorian Hahn
104175d68ddSFlorian Hahndefine i1 @test_same_cond_for_and(i8 %x) {
105175d68ddSFlorian Hahn; CHECK-LABEL: @test_same_cond_for_and(
106175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
107175d68ddSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
1087cf499c6SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[C_1]]
109175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
110175d68ddSFlorian Hahn; CHECK:       then:
111175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 false
112175d68ddSFlorian Hahn; CHECK:       else:
113175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 true
114175d68ddSFlorian Hahn;
115175d68ddSFlorian Hahnentry:
116175d68ddSFlorian Hahn  %c.1 = icmp ugt i8 %x, 10
117175d68ddSFlorian Hahn  %and = and i1 %c.1, %c.1
118175d68ddSFlorian Hahn  br i1 %and, label %then, label %else
119175d68ddSFlorian Hahn
120175d68ddSFlorian Hahnthen:
121175d68ddSFlorian Hahn  ret i1 0
122175d68ddSFlorian Hahn
123175d68ddSFlorian Hahnelse:
124175d68ddSFlorian Hahn  ret i1 1
125175d68ddSFlorian Hahn}
126175d68ddSFlorian Hahn
1270332f2c5SFlorian Hahndefine i1 @test_same_cond_for_and_select_form(i8 %x) {
1280332f2c5SFlorian Hahn; CHECK-LABEL: @test_same_cond_for_and_select_form(
1290332f2c5SFlorian Hahn; CHECK-NEXT:  entry:
1300332f2c5SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
1317cf499c6SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_1]], i1 [[C_1]], i1 false
1320332f2c5SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
1330332f2c5SFlorian Hahn; CHECK:       then:
1340332f2c5SFlorian Hahn; CHECK-NEXT:    ret i1 false
1350332f2c5SFlorian Hahn; CHECK:       else:
1360332f2c5SFlorian Hahn; CHECK-NEXT:    ret i1 true
1370332f2c5SFlorian Hahn;
1380332f2c5SFlorian Hahnentry:
1390332f2c5SFlorian Hahn  %c.1 = icmp ugt i8 %x, 10
1400332f2c5SFlorian Hahn  %and = select i1 %c.1, i1 %c.1, i1 false
1410332f2c5SFlorian Hahn  br i1 %and, label %then, label %else
1420332f2c5SFlorian Hahn
1430332f2c5SFlorian Hahnthen:
1440332f2c5SFlorian Hahn  ret i1 0
1450332f2c5SFlorian Hahn
1460332f2c5SFlorian Hahnelse:
1470332f2c5SFlorian Hahn  ret i1 1
1480332f2c5SFlorian Hahn}
1490332f2c5SFlorian Hahn
150175d68ddSFlorian Hahndefine i1 @test_second_and_condition_not_implied_by_first(i8 %x) {
151175d68ddSFlorian Hahn; CHECK-LABEL: @test_second_and_condition_not_implied_by_first(
152175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
153175d68ddSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
154175d68ddSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 5
1557cf499c6SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[C_1]]
156175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
157175d68ddSFlorian Hahn; CHECK:       then:
158175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 false
159175d68ddSFlorian Hahn; CHECK:       else:
160175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 true
161175d68ddSFlorian Hahn;
162175d68ddSFlorian Hahnentry:
163175d68ddSFlorian Hahn  %c.1 = icmp ugt i8 %x, 10
164175d68ddSFlorian Hahn  %c.2 = icmp ugt i8 %x, 5
165175d68ddSFlorian Hahn  %and = and i1 %c.2, %c.1
166175d68ddSFlorian Hahn  br i1 %and, label %then, label %else
167175d68ddSFlorian Hahn
168175d68ddSFlorian Hahnthen:
169175d68ddSFlorian Hahn  ret i1 0
170175d68ddSFlorian Hahn
171175d68ddSFlorian Hahnelse:
172175d68ddSFlorian Hahn  ret i1 1
173175d68ddSFlorian Hahn}
1740332f2c5SFlorian Hahn
1750332f2c5SFlorian Hahndefine i1 @test_remove_variables(i1 %c, ptr %A, i64 %B, ptr %C) {
1760332f2c5SFlorian Hahn; CHECK-LABEL: @test_remove_variables(
1770332f2c5SFlorian Hahn; CHECK-NEXT:  entry:
1780332f2c5SFlorian Hahn; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN_1:%.*]], label [[EXIT:%.*]]
1790332f2c5SFlorian Hahn; CHECK:       then.1:
1800332f2c5SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C:%.*]], align 8
1810332f2c5SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[TMP0]], [[A:%.*]]
1820332f2c5SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[THEN_2:%.*]], label [[ELSE_2:%.*]]
1830332f2c5SFlorian Hahn; CHECK:       then.2:
1840332f2c5SFlorian Hahn; CHECK-NEXT:    [[C_3:%.*]] = icmp sgt i64 [[B:%.*]], 0
185fbcf8a8cSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[C_3]]
1860332f2c5SFlorian Hahn; CHECK-NEXT:    ret i1 [[AND]]
1870332f2c5SFlorian Hahn; CHECK:       else.2:
1880332f2c5SFlorian Hahn; CHECK-NEXT:    ret i1 false
1890332f2c5SFlorian Hahn; CHECK:       exit:
1900332f2c5SFlorian Hahn; CHECK-NEXT:    ret i1 true
1910332f2c5SFlorian Hahn;
1920332f2c5SFlorian Hahnentry:
1930332f2c5SFlorian Hahn  br i1 %c, label %then.1, label %exit
1940332f2c5SFlorian Hahn
1950332f2c5SFlorian Hahnthen.1:
1960332f2c5SFlorian Hahn  %0 = load ptr, ptr %C, align 8
1970332f2c5SFlorian Hahn  %c.1 = icmp ult ptr %0, %A
1980332f2c5SFlorian Hahn  br i1 %c.1, label %then.2, label %else.2
1990332f2c5SFlorian Hahn
2000332f2c5SFlorian Hahnthen.2:
2010332f2c5SFlorian Hahn  %c.2 = icmp ne ptr %A, null
2020332f2c5SFlorian Hahn  %c.3 = icmp sgt i64 %B, 0
2030332f2c5SFlorian Hahn  %and = and i1 %c.2, %c.3
2040332f2c5SFlorian Hahn  ret i1 %and
2050332f2c5SFlorian Hahn
2060332f2c5SFlorian Hahnelse.2:
2070332f2c5SFlorian Hahn  ret i1 0
2080332f2c5SFlorian Hahn
2090332f2c5SFlorian Hahnexit:
2100332f2c5SFlorian Hahn  %t = icmp eq ptr null, null
2110332f2c5SFlorian Hahn  ret i1 %t
2120332f2c5SFlorian Hahn}
2130332f2c5SFlorian Hahn
2140332f2c5SFlorian Hahndefine i1 @test_and_op_0_simplified(i32 %v) {
2150332f2c5SFlorian Hahn; CHECK-LABEL: @test_and_op_0_simplified(
2160332f2c5SFlorian Hahn; CHECK-NEXT:  entry:
2170332f2c5SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0
2180332f2c5SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 false, [[C_1]]
2190332f2c5SFlorian Hahn; CHECK-NEXT:    ret i1 [[AND]]
2200332f2c5SFlorian Hahn;
2210332f2c5SFlorian Hahnentry:
2220332f2c5SFlorian Hahn  %c.1 = icmp sgt i32 %v, 0
2230332f2c5SFlorian Hahn  %t.1 = icmp sgt i32 0, 0
2240332f2c5SFlorian Hahn  %and = and i1 %t.1, %c.1
2250332f2c5SFlorian Hahn  ret i1 %and
2260332f2c5SFlorian Hahn}
2270332f2c5SFlorian Hahn
2280332f2c5SFlorian Hahndefine i1 @test_and_op_1_simplified(i32 %v) {
2290332f2c5SFlorian Hahn; CHECK-LABEL: @test_and_op_1_simplified(
2300332f2c5SFlorian Hahn; CHECK-NEXT:  entry:
2310332f2c5SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0
2320332f2c5SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], false
2330332f2c5SFlorian Hahn; CHECK-NEXT:    ret i1 [[AND]]
2340332f2c5SFlorian Hahn;
2350332f2c5SFlorian Hahnentry:
2360332f2c5SFlorian Hahn  %c.1 = icmp sgt i32 %v, 0
2370332f2c5SFlorian Hahn  %t.1 = icmp sgt i32 0, 0
2380332f2c5SFlorian Hahn  %and = and i1 %c.1, %t.1
2390332f2c5SFlorian Hahn  ret i1 %and
2400332f2c5SFlorian Hahn}
24102bf5e36SFlorian Hahn
24202bf5e36SFlorian Hahndefine i1 @and_select_not_used_for_branch(i32 %x, i32 %y,i32 %z) {
24302bf5e36SFlorian Hahn; CHECK-LABEL: @and_select_not_used_for_branch(
24402bf5e36SFlorian Hahn; CHECK-NEXT:  entry:
24502bf5e36SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i32 [[X:%.*]], 0
24602bf5e36SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i32 [[Y:%.*]], 0
24702bf5e36SFlorian Hahn; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i32 [[X]], 16
24802bf5e36SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_3]]
24902bf5e36SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[EXIT:%.*]]
25002bf5e36SFlorian Hahn; CHECK:       then:
25102bf5e36SFlorian Hahn; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i32 [[Z:%.*]], 0
2526c25c58aSFlorian Hahn; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C_4]], i1 true, i1 false
25302bf5e36SFlorian Hahn; CHECK-NEXT:    br label [[EXIT]]
25402bf5e36SFlorian Hahn; CHECK:       exit:
25502bf5e36SFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = phi i1 [ [[C_1]], [[ENTRY:%.*]] ], [ [[SEL]], [[THEN]] ]
25602bf5e36SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES]]
25702bf5e36SFlorian Hahn;
25802bf5e36SFlorian Hahnentry:
25902bf5e36SFlorian Hahn  %c.1 = icmp ne i32 %x, 0
26002bf5e36SFlorian Hahn  %c.2 = icmp ne i32 %y, 0
26102bf5e36SFlorian Hahn  %c.3 = icmp eq i32 %x, 16
26202bf5e36SFlorian Hahn  %and = and i1 %c.2, %c.3
26302bf5e36SFlorian Hahn  br i1 %and, label %then, label %exit
26402bf5e36SFlorian Hahn
26502bf5e36SFlorian Hahnthen:
26602bf5e36SFlorian Hahn  %c.4 = icmp eq i32 %z, 0
26702bf5e36SFlorian Hahn  %sel = select i1 %c.4, i1 %c.1, i1 false
26802bf5e36SFlorian Hahn  br label %exit
26902bf5e36SFlorian Hahn
27002bf5e36SFlorian Hahnexit:
27102bf5e36SFlorian Hahn  %res = phi i1 [ %c.1, %entry ], [ %sel, %then ]
27202bf5e36SFlorian Hahn  ret i1 %res
27302bf5e36SFlorian Hahn}
27402bf5e36SFlorian Hahn
27502bf5e36SFlorian Hahndefine i1 @and_select_scope_limited(i32 %x, i32 %y, i32 %z) {
27602bf5e36SFlorian Hahn; CHECK-LABEL: @and_select_scope_limited(
27702bf5e36SFlorian Hahn; CHECK-NEXT:  entry:
27802bf5e36SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i32 [[X:%.*]], 0
27902bf5e36SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i32 [[Y:%.*]], 0
28002bf5e36SFlorian Hahn; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i32 [[X]], 16
28102bf5e36SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_3]]
28202bf5e36SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[EXIT:%.*]]
28302bf5e36SFlorian Hahn; CHECK:       then:
28402bf5e36SFlorian Hahn; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i32 [[Z:%.*]], 0
2856c25c58aSFlorian Hahn; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C_4]], i1 true, i1 false
28602bf5e36SFlorian Hahn; CHECK-NEXT:    br i1 [[SEL]], label [[T_1:%.*]], label [[EXIT]]
28702bf5e36SFlorian Hahn; CHECK:       t.1:
2886c25c58aSFlorian Hahn; CHECK-NEXT:    ret i1 true
28902bf5e36SFlorian Hahn; CHECK:       exit:
29002bf5e36SFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = phi i1 [ [[C_1]], [[ENTRY:%.*]] ], [ [[SEL]], [[THEN]] ]
29102bf5e36SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES]]
29202bf5e36SFlorian Hahn;
29302bf5e36SFlorian Hahnentry:
29402bf5e36SFlorian Hahn  %c.1 = icmp ne i32 %x, 0
29502bf5e36SFlorian Hahn  %c.2 = icmp ne i32 %y, 0
29602bf5e36SFlorian Hahn  %c.3 = icmp eq i32 %x, 16
29702bf5e36SFlorian Hahn  %and = and i1 %c.2, %c.3
29802bf5e36SFlorian Hahn  br i1 %and, label %then, label %exit
29902bf5e36SFlorian Hahn
30002bf5e36SFlorian Hahnthen:
30102bf5e36SFlorian Hahn  %c.4 = icmp eq i32 %z, 0
30202bf5e36SFlorian Hahn  %sel = select i1 %c.4, i1 %c.1, i1 false
30302bf5e36SFlorian Hahn  br i1 %sel, label %t.1, label %exit
30402bf5e36SFlorian Hahn
30502bf5e36SFlorian Hahnt.1:
30602bf5e36SFlorian Hahn  ret i1 %c.1
30702bf5e36SFlorian Hahn
30802bf5e36SFlorian Hahnexit:
30902bf5e36SFlorian Hahn  %res = phi i1 [ %c.1, %entry ], [ %sel, %then ]
31002bf5e36SFlorian Hahn  ret i1 %res
31102bf5e36SFlorian Hahn}
31206dab8f7SFlorian Hahn
31306dab8f7SFlorian Hahndeclare void @use(ptr)
31406dab8f7SFlorian Hahn
31506dab8f7SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_eq_to_uge(ptr %start, i16 %len) {
31606dab8f7SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge(
31706dab8f7SFlorian Hahn; CHECK-NEXT:  entry:
31806dab8f7SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
31906dab8f7SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_PH:%.*]]
32006dab8f7SFlorian Hahn; CHECK:       loop.ph:
32106dab8f7SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
32206dab8f7SFlorian Hahn; CHECK:       loop.header:
32306dab8f7SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
32406dab8f7SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp sgt i16 [[LEN]], 0
32506dab8f7SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]
32606dab8f7SFlorian Hahn; CHECK-NEXT:    [[AND_0:%.*]] = and i1 [[LEN_NEG]], [[C]]
32706dab8f7SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_0]], label [[FOR_BODY:%.*]], label [[EXIT:%.*]]
32806dab8f7SFlorian Hahn; CHECK:       for.body:
32906dab8f7SFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
33006dab8f7SFlorian Hahn; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
33106dab8f7SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
33206dab8f7SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
33306dab8f7SFlorian Hahn; CHECK:       loop.latch:
33406dab8f7SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
33506dab8f7SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
33606dab8f7SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
33706dab8f7SFlorian Hahn; CHECK:       exit:
33806dab8f7SFlorian Hahn; CHECK-NEXT:    ret void
33906dab8f7SFlorian Hahn;
34006dab8f7SFlorian Hahnentry:
34106dab8f7SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %start, i16 %len
34206dab8f7SFlorian Hahn  br label %loop.ph
34306dab8f7SFlorian Hahn
34406dab8f7SFlorian Hahnloop.ph:
34506dab8f7SFlorian Hahn  br label %loop.header
34606dab8f7SFlorian Hahn
34706dab8f7SFlorian Hahnloop.header:
34806dab8f7SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
34906dab8f7SFlorian Hahn  %len.neg = icmp sgt i16 %len, 0
35006dab8f7SFlorian Hahn  %c = icmp ne ptr %ptr.iv, %upper
35106dab8f7SFlorian Hahn  %and.0 = and i1 %len.neg, %c
35206dab8f7SFlorian Hahn  br i1 %and.0, label %for.body, label %exit
35306dab8f7SFlorian Hahn
35406dab8f7SFlorian Hahnfor.body:
35506dab8f7SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
35606dab8f7SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
35706dab8f7SFlorian Hahn  %and = and i1 %t.1, %t.2
35806dab8f7SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
35906dab8f7SFlorian Hahn
36006dab8f7SFlorian Hahnloop.latch:
36106dab8f7SFlorian Hahn  call void @use(ptr %ptr.iv)
36206dab8f7SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
36306dab8f7SFlorian Hahn  br label %loop.header
36406dab8f7SFlorian Hahn
36506dab8f7SFlorian Hahnexit:
36606dab8f7SFlorian Hahn  ret void
36706dab8f7SFlorian Hahn}
368c52268a9SFlorian Hahn
369c52268a9SFlorian Hahndefine i1 @test_and_used_in_false_branch(i8 %x) {
370c52268a9SFlorian Hahn; CHECK-LABEL: @test_and_used_in_false_branch(
371c52268a9SFlorian Hahn; CHECK-NEXT:  entry:
372c52268a9SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
373c52268a9SFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
3740ad6879aSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], true
375c52268a9SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
376c52268a9SFlorian Hahn; CHECK:       then:
3776c25c58aSFlorian Hahn; CHECK-NEXT:    ret i1 true
378c52268a9SFlorian Hahn; CHECK:       else:
379c52268a9SFlorian Hahn; CHECK-NEXT:    ret i1 [[T_1]]
380c52268a9SFlorian Hahn;
381c52268a9SFlorian Hahn
382c52268a9SFlorian Hahnentry:
383c52268a9SFlorian Hahn  %c.1 = icmp ugt i8 %x, 10
384c52268a9SFlorian Hahn  %t.1 = icmp ugt i8 %x, 5
385c52268a9SFlorian Hahn  %and = and i1 %c.1, %t.1
386c52268a9SFlorian Hahn  br i1 %and, label %then, label %else
387c52268a9SFlorian Hahn
388c52268a9SFlorian Hahnthen:
389c52268a9SFlorian Hahn  ret i1 %t.1
390c52268a9SFlorian Hahn
391c52268a9SFlorian Hahnelse:
392c52268a9SFlorian Hahn  ret i1 %t.1
393c52268a9SFlorian Hahn}
394c52268a9SFlorian Hahn
395c52268a9SFlorian Hahndefine i1 @test_or_used_in_false_branch(i8 %x) {
396c52268a9SFlorian Hahn; CHECK-LABEL: @test_or_used_in_false_branch(
397c52268a9SFlorian Hahn; CHECK-NEXT:  entry:
398c52268a9SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
399c52268a9SFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[X]], 5
40018170d0fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = or i1 [[C_1]], false
401c52268a9SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
402c52268a9SFlorian Hahn; CHECK:       then:
403c52268a9SFlorian Hahn; CHECK-NEXT:    ret i1 [[T_1]]
404c52268a9SFlorian Hahn; CHECK:       else:
4056c25c58aSFlorian Hahn; CHECK-NEXT:    ret i1 false
406c52268a9SFlorian Hahn;
407c52268a9SFlorian Hahn
408c52268a9SFlorian Hahnentry:
409c52268a9SFlorian Hahn  %c.1 = icmp ule i8 %x, 10
410c52268a9SFlorian Hahn  %t.1 = icmp ule i8 %x, 5
411c52268a9SFlorian Hahn  %and = or i1 %c.1, %t.1
412c52268a9SFlorian Hahn  br i1 %and, label %then, label %else
413c52268a9SFlorian Hahn
414c52268a9SFlorian Hahnthen:
415c52268a9SFlorian Hahn  ret i1 %t.1
416c52268a9SFlorian Hahn
417c52268a9SFlorian Hahnelse:
418c52268a9SFlorian Hahn  ret i1 %t.1
419c52268a9SFlorian Hahn}
420c52268a9SFlorian Hahn
421c52268a9SFlorian Hahndefine i1 @test_or_used_in_false_branch2(i8 %x) {
422c52268a9SFlorian Hahn; CHECK-LABEL: @test_or_used_in_false_branch2(
423c52268a9SFlorian Hahn; CHECK-NEXT:  entry:
424c52268a9SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
425c52268a9SFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
42618170d0fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = or i1 false, [[T_1]]
427c52268a9SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
428c52268a9SFlorian Hahn; CHECK:       then:
429c52268a9SFlorian Hahn; CHECK-NEXT:    ret i1 [[T_1]]
430c52268a9SFlorian Hahn; CHECK:       else:
4316c25c58aSFlorian Hahn; CHECK-NEXT:    ret i1 false
432c52268a9SFlorian Hahn;
433c52268a9SFlorian Hahn
434c52268a9SFlorian Hahnentry:
435c52268a9SFlorian Hahn  %c.1 = icmp ugt i8 %x, 10
436c52268a9SFlorian Hahn  %t.1 = icmp ugt i8 %x, 5
437c52268a9SFlorian Hahn  %and = or i1 %c.1, %t.1
438c52268a9SFlorian Hahn  br i1 %and, label %then, label %else
439c52268a9SFlorian Hahn
440c52268a9SFlorian Hahnthen:
441c52268a9SFlorian Hahn  ret i1 %t.1
442c52268a9SFlorian Hahn
443c52268a9SFlorian Hahnelse:
444c52268a9SFlorian Hahn  ret i1 %t.1
445c52268a9SFlorian Hahn}
446c014454fSFlorian Hahn
447c014454fSFlorian Hahndefine i1 @and_select_first_implies_second_may_be_poison(ptr noundef %A, ptr noundef %B) {
448c014454fSFlorian Hahn; CHECK-LABEL: @and_select_first_implies_second_may_be_poison(
449c014454fSFlorian Hahn; CHECK-NEXT:  entry:
450c014454fSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]
451c014454fSFlorian Hahn; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1
452c014454fSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]
453c014454fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_2]], i1 true, i1 false
454c014454fSFlorian Hahn; CHECK-NEXT:    ret i1 [[AND]]
455c014454fSFlorian Hahn;
456c014454fSFlorian Hahnentry:
457c014454fSFlorian Hahn  %c.1 = icmp ne ptr %A, %B
458c014454fSFlorian Hahn  %gep = getelementptr inbounds ptr, ptr %B, i64 -1
459c014454fSFlorian Hahn  %c.2 = icmp ugt ptr %gep, %A
460c014454fSFlorian Hahn  %and = select i1 %c.2, i1 %c.1, i1 false
461c014454fSFlorian Hahn  ret i1 %and
462c014454fSFlorian Hahn}
463c014454fSFlorian Hahn
464c014454fSFlorian Hahndefine i1 @and_select_second_implies_first_may_be_poison(ptr noundef %A, ptr noundef %B) {
465c014454fSFlorian Hahn; CHECK-LABEL: @and_select_second_implies_first_may_be_poison(
466c014454fSFlorian Hahn; CHECK-NEXT:  entry:
467c014454fSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]
468c014454fSFlorian Hahn; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1
469c014454fSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]
470c014454fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false
471c014454fSFlorian Hahn; CHECK-NEXT:    ret i1 [[AND]]
472c014454fSFlorian Hahn;
473c014454fSFlorian Hahnentry:
474c014454fSFlorian Hahn  %c.1 = icmp ne ptr %A, %B
475c014454fSFlorian Hahn  %gep = getelementptr inbounds ptr, ptr %B, i64 -1
476c014454fSFlorian Hahn  %c.2 = icmp ugt ptr %gep, %A
477c014454fSFlorian Hahn  %and = select i1 %c.1, i1 %c.2, i1 false
478c014454fSFlorian Hahn  ret i1 %and
479c014454fSFlorian Hahn}
48068fb3d59SFlorian Hahn
48168fb3d59SFlorian Hahndefine i1 @and_select_second_implies_first_guaranteed_not_poison(ptr noundef %A, ptr noundef %B) {
48268fb3d59SFlorian Hahn; CHECK-LABEL: @and_select_second_implies_first_guaranteed_not_poison(
48368fb3d59SFlorian Hahn; CHECK-NEXT:  entry:
48468fb3d59SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]
48568fb3d59SFlorian Hahn; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1
48668fb3d59SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]
48768fb3d59SFlorian Hahn; CHECK-NEXT:    call void @no_noundef(i1 [[C_2]])
48868fb3d59SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false
48968fb3d59SFlorian Hahn; CHECK-NEXT:    ret i1 [[AND]]
49068fb3d59SFlorian Hahn;
49168fb3d59SFlorian Hahnentry:
49268fb3d59SFlorian Hahn  %c.1 = icmp ne ptr %A, %B
49368fb3d59SFlorian Hahn  %gep = getelementptr inbounds ptr, ptr %B, i64 -1
49468fb3d59SFlorian Hahn  %c.2 = icmp ugt ptr %gep, %A
49568fb3d59SFlorian Hahn  call void @no_noundef(i1 %c.2)
49668fb3d59SFlorian Hahn  %and = select i1 %c.1, i1 %c.2, i1 false
49768fb3d59SFlorian Hahn  ret i1 %and
49868fb3d59SFlorian Hahn}
49968fb3d59SFlorian Hahn
500*0f0c0c36SYingwei Zhengdefine void @and_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
501*0f0c0c36SYingwei Zheng; CHECK-LABEL: @and_tree_second_implies_first(
502*0f0c0c36SYingwei Zheng; CHECK-NEXT:  entry:
503*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
504*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
505*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP0]], [[CMP1]]
506*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
507*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND2:%.*]] = and i1 false, [[AND1]]
508*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
509*0f0c0c36SYingwei Zheng; CHECK:       if.then:
510*0f0c0c36SYingwei Zheng; CHECK-NEXT:    call void @side_effect()
511*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br label [[RETURN]]
512*0f0c0c36SYingwei Zheng; CHECK:       return:
513*0f0c0c36SYingwei Zheng; CHECK-NEXT:    ret void
514*0f0c0c36SYingwei Zheng;
515*0f0c0c36SYingwei Zhengentry:
516*0f0c0c36SYingwei Zheng  %cmp0 = icmp sge i32 %v0, %v1
517*0f0c0c36SYingwei Zheng  %cmp1 = icmp sge i32 %v1, %v2
518*0f0c0c36SYingwei Zheng  %and1 = and i1 %cmp0, %cmp1
519*0f0c0c36SYingwei Zheng  %cmp2 = icmp slt i32 %v0, %v2
520*0f0c0c36SYingwei Zheng  %and2 = and i1 %cmp2, %and1
521*0f0c0c36SYingwei Zheng  br i1 %and2, label %if.then, label %return
522*0f0c0c36SYingwei Zheng
523*0f0c0c36SYingwei Zhengif.then:
524*0f0c0c36SYingwei Zheng  call void @side_effect()
525*0f0c0c36SYingwei Zheng  br label %return
526*0f0c0c36SYingwei Zheng
527*0f0c0c36SYingwei Zhengreturn:
528*0f0c0c36SYingwei Zheng  ret void
529*0f0c0c36SYingwei Zheng}
530*0f0c0c36SYingwei Zheng
531*0f0c0c36SYingwei Zhengdefine void @and_tree_second_implies_first_perm1(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
532*0f0c0c36SYingwei Zheng; CHECK-LABEL: @and_tree_second_implies_first_perm1(
533*0f0c0c36SYingwei Zheng; CHECK-NEXT:  entry:
534*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
535*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
536*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
537*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP2]], [[CMP1]]
538*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND2:%.*]] = and i1 false, [[AND1]]
539*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
540*0f0c0c36SYingwei Zheng; CHECK:       if.then:
541*0f0c0c36SYingwei Zheng; CHECK-NEXT:    call void @side_effect()
542*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br label [[RETURN]]
543*0f0c0c36SYingwei Zheng; CHECK:       return:
544*0f0c0c36SYingwei Zheng; CHECK-NEXT:    ret void
545*0f0c0c36SYingwei Zheng;
546*0f0c0c36SYingwei Zhengentry:
547*0f0c0c36SYingwei Zheng  %cmp0 = icmp sge i32 %v0, %v1
548*0f0c0c36SYingwei Zheng  %cmp1 = icmp sge i32 %v1, %v2
549*0f0c0c36SYingwei Zheng  %cmp2 = icmp slt i32 %v0, %v2
550*0f0c0c36SYingwei Zheng  %and1 = and i1 %cmp2, %cmp1
551*0f0c0c36SYingwei Zheng  %and2 = and i1 %cmp0, %and1
552*0f0c0c36SYingwei Zheng  br i1 %and2, label %if.then, label %return
553*0f0c0c36SYingwei Zheng
554*0f0c0c36SYingwei Zhengif.then:
555*0f0c0c36SYingwei Zheng  call void @side_effect()
556*0f0c0c36SYingwei Zheng  br label %return
557*0f0c0c36SYingwei Zheng
558*0f0c0c36SYingwei Zhengreturn:
559*0f0c0c36SYingwei Zheng  ret void
560*0f0c0c36SYingwei Zheng}
561*0f0c0c36SYingwei Zheng
562*0f0c0c36SYingwei Zheng
563*0f0c0c36SYingwei Zhengdefine void @and_tree_second_implies_first_perm2(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
564*0f0c0c36SYingwei Zheng; CHECK-LABEL: @and_tree_second_implies_first_perm2(
565*0f0c0c36SYingwei Zheng; CHECK-NEXT:  entry:
566*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
567*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
568*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
569*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP0]], [[CMP2]]
570*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND2:%.*]] = and i1 false, [[AND1]]
571*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
572*0f0c0c36SYingwei Zheng; CHECK:       if.then:
573*0f0c0c36SYingwei Zheng; CHECK-NEXT:    call void @side_effect()
574*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br label [[RETURN]]
575*0f0c0c36SYingwei Zheng; CHECK:       return:
576*0f0c0c36SYingwei Zheng; CHECK-NEXT:    ret void
577*0f0c0c36SYingwei Zheng;
578*0f0c0c36SYingwei Zhengentry:
579*0f0c0c36SYingwei Zheng  %cmp0 = icmp sge i32 %v0, %v1
580*0f0c0c36SYingwei Zheng  %cmp1 = icmp sge i32 %v1, %v2
581*0f0c0c36SYingwei Zheng  %cmp2 = icmp slt i32 %v0, %v2
582*0f0c0c36SYingwei Zheng  %and1 = and i1 %cmp0, %cmp2
583*0f0c0c36SYingwei Zheng  %and2 = and i1 %cmp1, %and1
584*0f0c0c36SYingwei Zheng  br i1 %and2, label %if.then, label %return
585*0f0c0c36SYingwei Zheng
586*0f0c0c36SYingwei Zhengif.then:
587*0f0c0c36SYingwei Zheng  call void @side_effect()
588*0f0c0c36SYingwei Zheng  br label %return
589*0f0c0c36SYingwei Zheng
590*0f0c0c36SYingwei Zhengreturn:
591*0f0c0c36SYingwei Zheng  ret void
592*0f0c0c36SYingwei Zheng}
593*0f0c0c36SYingwei Zheng
594*0f0c0c36SYingwei Zhengdefine void @logical_and_tree_second_implies_first(i32 %v0, i32 %v1, i32 %v2) {
595*0f0c0c36SYingwei Zheng; CHECK-LABEL: @logical_and_tree_second_implies_first(
596*0f0c0c36SYingwei Zheng; CHECK-NEXT:  entry:
597*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
598*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
599*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[CMP0]], i1 [[CMP1]], i1 false
600*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
601*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[CMP2]], i1 [[AND1]], i1 false
602*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
603*0f0c0c36SYingwei Zheng; CHECK:       if.then:
604*0f0c0c36SYingwei Zheng; CHECK-NEXT:    call void @side_effect()
605*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br label [[RETURN]]
606*0f0c0c36SYingwei Zheng; CHECK:       return:
607*0f0c0c36SYingwei Zheng; CHECK-NEXT:    ret void
608*0f0c0c36SYingwei Zheng;
609*0f0c0c36SYingwei Zhengentry:
610*0f0c0c36SYingwei Zheng  %cmp0 = icmp sge i32 %v0, %v1
611*0f0c0c36SYingwei Zheng  %cmp1 = icmp sge i32 %v1, %v2
612*0f0c0c36SYingwei Zheng  %and1 = select i1 %cmp0, i1 %cmp1, i1 false
613*0f0c0c36SYingwei Zheng  %cmp2 = icmp slt i32 %v0, %v2
614*0f0c0c36SYingwei Zheng  %and2 = select i1 %cmp2, i1 %and1, i1 false
615*0f0c0c36SYingwei Zheng  br i1 %and2, label %if.then, label %return
616*0f0c0c36SYingwei Zheng
617*0f0c0c36SYingwei Zhengif.then:
618*0f0c0c36SYingwei Zheng  call void @side_effect()
619*0f0c0c36SYingwei Zheng  br label %return
620*0f0c0c36SYingwei Zheng
621*0f0c0c36SYingwei Zhengreturn:
622*0f0c0c36SYingwei Zheng  ret void
623*0f0c0c36SYingwei Zheng}
624*0f0c0c36SYingwei Zheng
625*0f0c0c36SYingwei Zhengdefine void @or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
626*0f0c0c36SYingwei Zheng; CHECK-LABEL: @or_tree_second_implies_first(
627*0f0c0c36SYingwei Zheng; CHECK-NEXT:  entry:
628*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
629*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
630*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]
631*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
632*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND2:%.*]] = or i1 true, [[AND1]]
633*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
634*0f0c0c36SYingwei Zheng; CHECK:       if.then:
635*0f0c0c36SYingwei Zheng; CHECK-NEXT:    call void @side_effect()
636*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br label [[RETURN]]
637*0f0c0c36SYingwei Zheng; CHECK:       return:
638*0f0c0c36SYingwei Zheng; CHECK-NEXT:    ret void
639*0f0c0c36SYingwei Zheng;
640*0f0c0c36SYingwei Zhengentry:
641*0f0c0c36SYingwei Zheng  %cmp0 = icmp sge i32 %v0, %v1
642*0f0c0c36SYingwei Zheng  %cmp1 = icmp sge i32 %v1, %v2
643*0f0c0c36SYingwei Zheng  %and1 = or i1 %cmp0, %cmp1
644*0f0c0c36SYingwei Zheng  %cmp2 = icmp slt i32 %v0, %v2
645*0f0c0c36SYingwei Zheng  %and2 = or i1 %cmp2, %and1
646*0f0c0c36SYingwei Zheng  br i1 %and2, label %if.then, label %return
647*0f0c0c36SYingwei Zheng
648*0f0c0c36SYingwei Zhengif.then:
649*0f0c0c36SYingwei Zheng  call void @side_effect()
650*0f0c0c36SYingwei Zheng  br label %return
651*0f0c0c36SYingwei Zheng
652*0f0c0c36SYingwei Zhengreturn:
653*0f0c0c36SYingwei Zheng  ret void
654*0f0c0c36SYingwei Zheng}
655*0f0c0c36SYingwei Zheng
656*0f0c0c36SYingwei Zhengdefine void @or_tree_second_implies_first_with_unknown_cond(i64 %x, i1 %cond) {
657*0f0c0c36SYingwei Zheng; CHECK-LABEL: @or_tree_second_implies_first_with_unknown_cond(
658*0f0c0c36SYingwei Zheng; CHECK-NEXT:  entry:
659*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], 1
660*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[OR1:%.*]] = select i1 [[CMP1]], i1 [[COND:%.*]], i1 false
661*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[X]], 2
662*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[OR2:%.*]] = select i1 [[OR1]], i1 false, i1 false
663*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br i1 [[OR2]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
664*0f0c0c36SYingwei Zheng; CHECK:       if.then:
665*0f0c0c36SYingwei Zheng; CHECK-NEXT:    call void @side_effect()
666*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br label [[IF_END]]
667*0f0c0c36SYingwei Zheng; CHECK:       if.end:
668*0f0c0c36SYingwei Zheng; CHECK-NEXT:    ret void
669*0f0c0c36SYingwei Zheng;
670*0f0c0c36SYingwei Zhengentry:
671*0f0c0c36SYingwei Zheng  %cmp1 = icmp ugt i64 %x, 1
672*0f0c0c36SYingwei Zheng  %or1 = select i1 %cmp1, i1 %cond, i1 false
673*0f0c0c36SYingwei Zheng  %cmp2 = icmp ult i64 %x, 2
674*0f0c0c36SYingwei Zheng  %or2 = select i1 %or1, i1 %cmp2, i1 false
675*0f0c0c36SYingwei Zheng  br i1 %or2, label %if.then, label %if.end
676*0f0c0c36SYingwei Zheng
677*0f0c0c36SYingwei Zhengif.then:
678*0f0c0c36SYingwei Zheng  call void @side_effect()
679*0f0c0c36SYingwei Zheng  br label %if.end
680*0f0c0c36SYingwei Zheng
681*0f0c0c36SYingwei Zhengif.end:
682*0f0c0c36SYingwei Zheng  ret void
683*0f0c0c36SYingwei Zheng}
684*0f0c0c36SYingwei Zheng
685*0f0c0c36SYingwei Zhengdefine void @negative_and_or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
686*0f0c0c36SYingwei Zheng; CHECK-LABEL: @negative_and_or_tree_second_implies_first(
687*0f0c0c36SYingwei Zheng; CHECK-NEXT:  entry:
688*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
689*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
690*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]
691*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
692*0f0c0c36SYingwei Zheng; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[CMP2]], [[AND1]]
693*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
694*0f0c0c36SYingwei Zheng; CHECK:       if.then:
695*0f0c0c36SYingwei Zheng; CHECK-NEXT:    call void @side_effect()
696*0f0c0c36SYingwei Zheng; CHECK-NEXT:    br label [[RETURN]]
697*0f0c0c36SYingwei Zheng; CHECK:       return:
698*0f0c0c36SYingwei Zheng; CHECK-NEXT:    ret void
699*0f0c0c36SYingwei Zheng;
700*0f0c0c36SYingwei Zhengentry:
701*0f0c0c36SYingwei Zheng  %cmp0 = icmp sge i32 %v0, %v1
702*0f0c0c36SYingwei Zheng  %cmp1 = icmp sge i32 %v1, %v2
703*0f0c0c36SYingwei Zheng  %and1 = or i1 %cmp0, %cmp1
704*0f0c0c36SYingwei Zheng  %cmp2 = icmp slt i32 %v0, %v2
705*0f0c0c36SYingwei Zheng  %and2 = and i1 %cmp2, %and1
706*0f0c0c36SYingwei Zheng  br i1 %and2, label %if.then, label %return
707*0f0c0c36SYingwei Zheng
708*0f0c0c36SYingwei Zhengif.then:
709*0f0c0c36SYingwei Zheng  call void @side_effect()
710*0f0c0c36SYingwei Zheng  br label %return
711*0f0c0c36SYingwei Zheng
712*0f0c0c36SYingwei Zhengreturn:
713*0f0c0c36SYingwei Zheng  ret void
714*0f0c0c36SYingwei Zheng}
715*0f0c0c36SYingwei Zheng
716*0f0c0c36SYingwei Zhengdeclare void @side_effect()
71768fb3d59SFlorian Hahndeclare void @no_noundef(i1 noundef)
718