xref: /llvm-project/llvm/test/Transforms/InstCombine/select-cmp-br.ll (revision 462cb3cd6cecd0511ecaf0e3ebcaba455ece587d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; Replace a 'select' with 'or' in 'select - cmp [eq|ne] - br' sequence
3; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4
5%struct.S = type { ptr, i32, i32 }
6%C = type <{ %struct.S }>
7
8declare void @bar(ptr)
9declare void @foobar()
10
11define void @test1(ptr %arg) {
12; CHECK-LABEL: @test1(
13; CHECK-NEXT:  entry:
14; CHECK-NEXT:    [[M:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
15; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG]], i64 16
16; CHECK-NEXT:    [[N:%.*]] = load ptr, ptr [[TMP1]], align 8
17; CHECK-NEXT:    [[TMP5_NOT:%.*]] = icmp eq ptr [[M]], [[N]]
18; CHECK-NEXT:    br i1 [[TMP5_NOT]], label [[BB8:%.*]], label [[BB10:%.*]]
19; CHECK:       bb:
20; CHECK-NEXT:    ret void
21; CHECK:       bb8:
22; CHECK-NEXT:    tail call void @bar(ptr nonnull [[ARG]])
23; CHECK-NEXT:    br label [[BB:%.*]]
24; CHECK:       bb10:
25; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[M]], i64 72
26; CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[TMP2]], align 8
27; CHECK-NEXT:    [[TMP11:%.*]] = tail call i64 [[TMP4]](ptr nonnull [[ARG]])
28; CHECK-NEXT:    br label [[BB]]
29;
30entry:
31  %m = load ptr, ptr %arg, align 8
32  %tmp1 = getelementptr inbounds %C, ptr %arg, i64 1, i32 0, i32 0
33  %n = load ptr, ptr %tmp1, align 8
34  %tmp2 = getelementptr inbounds i64, ptr %m, i64 9
35  %tmp4 = load ptr, ptr %tmp2, align 8
36  %tmp5 = icmp eq ptr %m, %n
37  %tmp6 = select i1 %tmp5, ptr %arg, ptr null
38  %tmp7 = icmp eq ptr %tmp6, null
39  br i1 %tmp7, label %bb10, label %bb8
40
41bb:                                               ; preds = %bb10, %bb8
42  ret void
43
44bb8:                                              ; preds = %entry
45  tail call void @bar(ptr %tmp6)
46  br label %bb
47
48bb10:                                             ; preds = %entry
49  %tmp11 = tail call i64 %tmp4(ptr %arg)
50  br label %bb
51}
52
53define void @test2(ptr %arg) {
54; CHECK-LABEL: @test2(
55; CHECK-NEXT:  entry:
56; CHECK-NEXT:    [[M:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
57; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG]], i64 16
58; CHECK-NEXT:    [[N:%.*]] = load ptr, ptr [[TMP1]], align 8
59; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq ptr [[M]], [[N]]
60; CHECK-NEXT:    br i1 [[TMP5]], label [[BB10:%.*]], label [[BB8:%.*]]
61; CHECK:       bb:
62; CHECK-NEXT:    ret void
63; CHECK:       bb8:
64; CHECK-NEXT:    tail call void @bar(ptr nonnull [[ARG]])
65; CHECK-NEXT:    br label [[BB:%.*]]
66; CHECK:       bb10:
67; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[M]], i64 72
68; CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[TMP2]], align 8
69; CHECK-NEXT:    [[TMP11:%.*]] = tail call i64 [[TMP4]](ptr nonnull [[ARG]])
70; CHECK-NEXT:    br label [[BB]]
71;
72entry:
73  %m = load ptr, ptr %arg, align 8
74  %tmp1 = getelementptr inbounds %C, ptr %arg, i64 1, i32 0, i32 0
75  %n = load ptr, ptr %tmp1, align 8
76  %tmp2 = getelementptr inbounds i64, ptr %m, i64 9
77  %tmp4 = load ptr, ptr %tmp2, align 8
78  %tmp5 = icmp eq ptr %m, %n
79  %tmp6 = select i1 %tmp5, ptr null, ptr %arg
80  %tmp7 = icmp eq ptr %tmp6, null
81  br i1 %tmp7, label %bb10, label %bb8
82
83bb:                                               ; preds = %bb10, %bb8
84  ret void
85
86bb8:                                              ; preds = %entry
87  tail call void @bar(ptr %tmp6)
88  br label %bb
89
90bb10:                                             ; preds = %entry
91  %tmp11 = tail call i64 %tmp4(ptr %arg)
92  br label %bb
93}
94
95define void @test3(ptr %arg) {
96; CHECK-LABEL: @test3(
97; CHECK-NEXT:  entry:
98; CHECK-NEXT:    [[M:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
99; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG]], i64 16
100; CHECK-NEXT:    [[N:%.*]] = load ptr, ptr [[TMP1]], align 8
101; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq ptr [[M]], [[N]]
102; CHECK-NEXT:    br i1 [[TMP5]], label [[BB8:%.*]], label [[BB10:%.*]]
103; CHECK:       bb:
104; CHECK-NEXT:    ret void
105; CHECK:       bb8:
106; CHECK-NEXT:    tail call void @bar(ptr nonnull [[ARG]])
107; CHECK-NEXT:    br label [[BB:%.*]]
108; CHECK:       bb10:
109; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[M]], i64 72
110; CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[TMP2]], align 8
111; CHECK-NEXT:    [[TMP11:%.*]] = tail call i64 [[TMP4]](ptr nonnull [[ARG]])
112; CHECK-NEXT:    br label [[BB]]
113;
114entry:
115  %m = load ptr, ptr %arg, align 8
116  %tmp1 = getelementptr inbounds %C, ptr %arg, i64 1, i32 0, i32 0
117  %n = load ptr, ptr %tmp1, align 8
118  %tmp2 = getelementptr inbounds i64, ptr %m, i64 9
119  %tmp4 = load ptr, ptr %tmp2, align 8
120  %tmp5 = icmp eq ptr %m, %n
121  %tmp6 = select i1 %tmp5, ptr %arg, ptr null
122  %tmp7 = icmp ne ptr %tmp6, null
123  br i1 %tmp7, label %bb8, label %bb10
124
125bb:                                               ; preds = %bb10, %bb8
126  ret void
127
128bb8:                                              ; preds = %entry
129  tail call void @bar(ptr %tmp6)
130  br label %bb
131
132bb10:                                             ; preds = %entry
133  %tmp11 = tail call i64 %tmp4(ptr %arg)
134  br label %bb
135}
136
137define void @test4(ptr %arg) {
138; CHECK-LABEL: @test4(
139; CHECK-NEXT:  entry:
140; CHECK-NEXT:    [[M:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
141; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG]], i64 16
142; CHECK-NEXT:    [[N:%.*]] = load ptr, ptr [[TMP1]], align 8
143; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq ptr [[M]], [[N]]
144; CHECK-NEXT:    br i1 [[TMP5]], label [[BB10:%.*]], label [[BB8:%.*]]
145; CHECK:       bb:
146; CHECK-NEXT:    ret void
147; CHECK:       bb8:
148; CHECK-NEXT:    tail call void @bar(ptr nonnull [[ARG]])
149; CHECK-NEXT:    br label [[BB:%.*]]
150; CHECK:       bb10:
151; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[M]], i64 72
152; CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[TMP2]], align 8
153; CHECK-NEXT:    [[TMP11:%.*]] = tail call i64 [[TMP4]](ptr nonnull [[ARG]])
154; CHECK-NEXT:    br label [[BB]]
155;
156entry:
157  %m = load ptr, ptr %arg, align 8
158  %tmp1 = getelementptr inbounds %C, ptr %arg, i64 1, i32 0, i32 0
159  %n = load ptr, ptr %tmp1, align 8
160  %tmp2 = getelementptr inbounds i64, ptr %m, i64 9
161  %tmp4 = load ptr, ptr %tmp2, align 8
162  %tmp5 = icmp eq ptr %m, %n
163  %tmp6 = select i1 %tmp5, ptr null, ptr %arg
164  %tmp7 = icmp ne ptr %tmp6, null
165  br i1 %tmp7, label %bb8, label %bb10
166
167bb:                                               ; preds = %bb10, %bb8
168  ret void
169
170bb8:                                              ; preds = %entry
171  tail call void @bar(ptr %tmp6)
172  br label %bb
173
174bb10:                                             ; preds = %entry
175  %tmp11 = tail call i64 %tmp4(ptr %arg)
176  br label %bb
177}
178
179define void @test5(ptr %arg, i1 %arg1) {
180; CHECK-LABEL: @test5(
181; CHECK-NEXT:  entry:
182; CHECK-NEXT:    [[TMP2_NOT1:%.*]] = icmp eq ptr [[ARG:%.*]], null
183; CHECK-NEXT:    [[TMP2_NOT:%.*]] = select i1 [[ARG1:%.*]], i1 true, i1 [[TMP2_NOT1]]
184; CHECK-NEXT:    br i1 [[TMP2_NOT]], label [[BB5:%.*]], label [[BB3:%.*]]
185; CHECK:       bb:
186; CHECK-NEXT:    ret void
187; CHECK:       bb3:
188; CHECK-NEXT:    tail call void @bar(ptr [[ARG]])
189; CHECK-NEXT:    br label [[BB:%.*]]
190; CHECK:       bb5:
191; CHECK-NEXT:    tail call void @foobar()
192; CHECK-NEXT:    br label [[BB]]
193;
194entry:
195  %tmp = select i1 %arg1, ptr null, ptr %arg
196  %tmp2 = icmp ne ptr %tmp, null
197  br i1 %tmp2, label %bb3, label %bb5
198
199bb:                                               ; preds = %bb5, %bb3
200  ret void
201
202bb3:                                              ; preds = %entry
203  tail call void @bar(ptr %tmp)
204  br label %bb
205
206bb5:                                              ; preds = %entry
207  tail call void @foobar()
208  br label %bb
209}
210
211; Negative test. Must not trigger the select-cmp-br combine because the result
212; of the select is used in both flows following the br (the special case where
213; the conditional branch has the same target for both flows).
214define i32 @test6(i32 %arg, i1 %arg1) {
215; CHECK-LABEL: @test6(
216; CHECK-NEXT:  entry:
217; CHECK-NEXT:    br i1 false, label [[BB:%.*]], label [[BB]]
218; CHECK:       bb:
219; CHECK-NEXT:    [[TMP:%.*]] = select i1 [[ARG1:%.*]], i32 [[ARG:%.*]], i32 0
220; CHECK-NEXT:    ret i32 [[TMP]]
221;
222entry:
223  %tmp = select i1 %arg1, i32 %arg, i32 0
224  %tmp2 = icmp eq i32 %tmp, 0
225  br i1 %tmp2, label %bb, label %bb
226
227bb:                                               ; preds = %entry, %entry
228  ret i32 %tmp
229}
230