1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S < %s -instcombine | FileCheck %s
3; RUN: opt -S < %s -passes=instcombine | FileCheck %s
4
5define i1 @test_direct_implication(i1 %cond) {
6; CHECK-LABEL: @test_direct_implication(
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
9; CHECK:       if.true:
10; CHECK-NEXT:    br label [[MERGE:%.*]]
11; CHECK:       if.false:
12; CHECK-NEXT:    br label [[MERGE]]
13; CHECK:       merge:
14; CHECK-NEXT:    ret i1 [[COND]]
15;
16entry:
17  br i1 %cond, label %if.true, label %if.false
18
19if.true:
20  br label %merge
21
22if.false:
23  br label %merge
24
25merge:
26  %ret = phi i1 [true, %if.true], [false, %if.false]
27  ret i1 %ret
28}
29
30define i1 @test_inverted_implication(i1 %cond) {
31; CHECK-LABEL: @test_inverted_implication(
32; CHECK-NEXT:  entry:
33; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
34; CHECK:       if.true:
35; CHECK-NEXT:    br label [[MERGE:%.*]]
36; CHECK:       if.false:
37; CHECK-NEXT:    br label [[MERGE]]
38; CHECK:       merge:
39; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND]], true
40; CHECK-NEXT:    ret i1 [[TMP0]]
41;
42entry:
43  br i1 %cond, label %if.true, label %if.false
44
45if.true:
46  br label %merge
47
48if.false:
49  br label %merge
50
51merge:
52  %ret = phi i1 [false, %if.true], [true, %if.false]
53  ret i1 %ret
54}
55
56define i1 @test_direct_implication_complex_cfg(i1 %cond, i32 %cnt1) {
57; CHECK-LABEL: @test_direct_implication_complex_cfg(
58; CHECK-NEXT:  entry:
59; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
60; CHECK:       if.true:
61; CHECK-NEXT:    br label [[LOOP1:%.*]]
62; CHECK:       loop1:
63; CHECK-NEXT:    [[IV1:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[IV1_NEXT:%.*]], [[LOOP1]] ]
64; CHECK-NEXT:    [[IV1_NEXT]] = add i32 [[IV1]], 1
65; CHECK-NEXT:    [[LOOP_COND_1:%.*]] = icmp slt i32 [[IV1_NEXT]], [[CNT1:%.*]]
66; CHECK-NEXT:    br i1 [[LOOP_COND_1]], label [[LOOP1]], label [[IF_TRUE_END:%.*]]
67; CHECK:       if.true.end:
68; CHECK-NEXT:    br label [[MERGE:%.*]]
69; CHECK:       if.false:
70; CHECK-NEXT:    br label [[MERGE]]
71; CHECK:       merge:
72; CHECK-NEXT:    ret i1 [[COND]]
73;
74entry:
75  br i1 %cond, label %if.true, label %if.false
76
77if.true:
78  br label %loop1
79
80loop1:
81  %iv1 = phi i32 [0, %if.true], [%iv1.next, %loop1]
82  %iv1.next = add i32 %iv1, 1
83  %loop.cond.1 = icmp slt i32 %iv1.next, %cnt1
84  br i1 %loop.cond.1, label %loop1, label %if.true.end
85
86if.true.end:
87  br label %merge
88
89if.false:
90  br label %merge
91
92merge:
93  %ret = phi i1 [true, %if.true.end], [false, %if.false]
94  ret i1 %ret
95}
96
97define i1 @test_inverted_implication_complex_cfg(i1 %cond, i32 %cnt1) {
98; CHECK-LABEL: @test_inverted_implication_complex_cfg(
99; CHECK-NEXT:  entry:
100; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
101; CHECK:       if.true:
102; CHECK-NEXT:    br label [[LOOP1:%.*]]
103; CHECK:       loop1:
104; CHECK-NEXT:    [[IV1:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[IV1_NEXT:%.*]], [[LOOP1]] ]
105; CHECK-NEXT:    [[IV1_NEXT]] = add i32 [[IV1]], 1
106; CHECK-NEXT:    [[LOOP_COND_1:%.*]] = icmp slt i32 [[IV1_NEXT]], [[CNT1:%.*]]
107; CHECK-NEXT:    br i1 [[LOOP_COND_1]], label [[LOOP1]], label [[IF_TRUE_END:%.*]]
108; CHECK:       if.true.end:
109; CHECK-NEXT:    br label [[MERGE:%.*]]
110; CHECK:       if.false:
111; CHECK-NEXT:    br label [[MERGE]]
112; CHECK:       merge:
113; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND]], true
114; CHECK-NEXT:    ret i1 [[TMP0]]
115;
116entry:
117  br i1 %cond, label %if.true, label %if.false
118
119if.true:
120  br label %loop1
121
122loop1:
123  %iv1 = phi i32 [0, %if.true], [%iv1.next, %loop1]
124  %iv1.next = add i32 %iv1, 1
125  %loop.cond.1 = icmp slt i32 %iv1.next, %cnt1
126  br i1 %loop.cond.1, label %loop1, label %if.true.end
127
128if.true.end:
129  br label %merge
130
131if.false:
132  br label %merge
133
134merge:
135  %ret = phi i1 [false, %if.true.end], [true, %if.false]
136  ret i1 %ret
137}
138