1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 define void @idom_sign_bit_check_edge_dominates(i64 %a) {
5 ; CHECK-LABEL: @idom_sign_bit_check_edge_dominates(
7 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
8 ; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
9 ; CHECK: land.lhs.true:
10 ; CHECK-NEXT: br label [[LOR_END:%.*]]
12 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[A]], 0
13 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOR_END]], label [[LAND_RHS:%.*]]
15 ; CHECK-NEXT: br label [[LOR_END]]
17 ; CHECK-NEXT: ret void
20 %cmp = icmp slt i64 %a, 0
21 br i1 %cmp, label %land.lhs.true, label %lor.rhs
27 %cmp2 = icmp sgt i64 %a, 0
28 br i1 %cmp2, label %land.rhs, label %lor.end
37 define void @idom_sign_bit_check_edge_not_dominates(i64 %a) {
38 ; CHECK-LABEL: @idom_sign_bit_check_edge_not_dominates(
40 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
41 ; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
42 ; CHECK: land.lhs.true:
43 ; CHECK-NEXT: br i1 undef, label [[LOR_END:%.*]], label [[LOR_RHS]]
45 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[A]], 0
46 ; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
48 ; CHECK-NEXT: br label [[LOR_END]]
50 ; CHECK-NEXT: ret void
53 %cmp = icmp slt i64 %a, 0
54 br i1 %cmp, label %land.lhs.true, label %lor.rhs
57 br i1 undef, label %lor.end, label %lor.rhs
60 %cmp2 = icmp sgt i64 %a, 0
61 br i1 %cmp2, label %land.rhs, label %lor.end
70 define void @idom_sign_bit_check_edge_dominates_select(i64 %a, i64 %b) {
71 ; CHECK-LABEL: @idom_sign_bit_check_edge_dominates_select(
73 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 5
74 ; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
75 ; CHECK: land.lhs.true:
76 ; CHECK-NEXT: br label [[LOR_END:%.*]]
78 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i64 [[A]], [[B:%.*]]
79 ; CHECK-NEXT: br i1 [[CMP3]], label [[LOR_END]], label [[LAND_RHS:%.*]]
81 ; CHECK-NEXT: br label [[LOR_END]]
83 ; CHECK-NEXT: ret void
86 %cmp = icmp slt i64 %a, 5
87 br i1 %cmp, label %land.lhs.true, label %lor.rhs
93 %cmp2 = icmp sgt i64 %a, 5
94 %select = select i1 %cmp2, i64 %a, i64 5
95 %cmp3 = icmp ne i64 %select, %b
96 br i1 %cmp3, label %land.rhs, label %lor.end
105 define void @idom_zbranch(i64 %a) {
106 ; CHECK-LABEL: @idom_zbranch(
108 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[A:%.*]], 0
109 ; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]]
111 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[A]], 0
112 ; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
114 ; CHECK-NEXT: br label [[LOR_END]]
116 ; CHECK-NEXT: ret void
119 %cmp = icmp sgt i64 %a, 0
120 br i1 %cmp, label %lor.end, label %lor.rhs
123 %cmp2 = icmp slt i64 %a, 0
124 br i1 %cmp2, label %land.rhs, label %lor.end
133 define void @idom_not_zbranch(i32 %a, i32 %b) {
134 ; CHECK-LABEL: @idom_not_zbranch(
136 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
137 ; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[IF_END:%.*]]
139 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], [[B:%.*]]
140 ; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN]], label [[IF_THEN3:%.*]]
142 ; CHECK-NEXT: br label [[RETURN]]
144 ; CHECK-NEXT: ret void
147 %cmp = icmp sgt i32 %a, 0
148 br i1 %cmp, label %return, label %if.end
151 %cmp1 = icmp slt i32 %a, 0
152 %a. = select i1 %cmp1, i32 %a, i32 0
153 %cmp2 = icmp ne i32 %a., %b
154 br i1 %cmp2, label %if.then3, label %return
163 define i1 @trueblock_cmp_is_false(i32 %x, i32 %y) {
164 ; CHECK-LABEL: @trueblock_cmp_is_false(
166 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
167 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
169 ; CHECK-NEXT: ret i1 false
171 ; CHECK-NEXT: ret i1 [[CMP]]
174 %cmp = icmp sgt i32 %x, %y
175 br i1 %cmp, label %t, label %f
177 %cmp2 = icmp slt i32 %x, %y
183 define i1 @trueblock_cmp_is_false_commute(i32 %x, i32 %y) {
184 ; CHECK-LABEL: @trueblock_cmp_is_false_commute(
186 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
187 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
189 ; CHECK-NEXT: ret i1 false
191 ; CHECK-NEXT: ret i1 [[CMP]]
194 %cmp = icmp eq i32 %x, %y
195 br i1 %cmp, label %t, label %f
197 %cmp2 = icmp sgt i32 %y, %x
203 define i1 @trueblock_cmp_is_true(i32 %x, i32 %y) {
204 ; CHECK-LABEL: @trueblock_cmp_is_true(
206 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
207 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
209 ; CHECK-NEXT: ret i1 true
211 ; CHECK-NEXT: ret i1 [[CMP]]
214 %cmp = icmp ult i32 %x, %y
215 br i1 %cmp, label %t, label %f
217 %cmp2 = icmp ne i32 %x, %y
223 define i1 @trueblock_cmp_is_true_commute(i32 %x, i32 %y) {
224 ; CHECK-LABEL: @trueblock_cmp_is_true_commute(
226 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
227 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
229 ; CHECK-NEXT: ret i1 true
231 ; CHECK-NEXT: ret i1 [[CMP]]
234 %cmp = icmp ugt i32 %x, %y
235 br i1 %cmp, label %t, label %f
237 %cmp2 = icmp ne i32 %y, %x
243 define i1 @falseblock_cmp_is_false(i32 %x, i32 %y) {
244 ; CHECK-LABEL: @falseblock_cmp_is_false(
246 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
247 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
249 ; CHECK-NEXT: ret i1 [[CMP]]
251 ; CHECK-NEXT: ret i1 false
254 %cmp = icmp sle i32 %x, %y
255 br i1 %cmp, label %t, label %f
259 %cmp2 = icmp slt i32 %x, %y
263 define i1 @falseblock_cmp_is_false_commute(i32 %x, i32 %y) {
264 ; CHECK-LABEL: @falseblock_cmp_is_false_commute(
266 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
267 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
269 ; CHECK-NEXT: ret i1 [[CMP]]
271 ; CHECK-NEXT: ret i1 false
274 %cmp = icmp eq i32 %x, %y
275 br i1 %cmp, label %t, label %f
279 %cmp2 = icmp eq i32 %y, %x
283 define i1 @falseblock_cmp_is_true(i32 %x, i32 %y) {
284 ; CHECK-LABEL: @falseblock_cmp_is_true(
286 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
287 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
289 ; CHECK-NEXT: ret i1 [[CMP]]
291 ; CHECK-NEXT: ret i1 true
294 %cmp = icmp ult i32 %x, %y
295 br i1 %cmp, label %t, label %f
299 %cmp2 = icmp uge i32 %x, %y
303 define i1 @falseblock_cmp_is_true_commute(i32 %x, i32 %y) {
304 ; CHECK-LABEL: @falseblock_cmp_is_true_commute(
306 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
307 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
309 ; CHECK-NEXT: ret i1 [[CMP]]
311 ; CHECK-NEXT: ret i1 true
314 %cmp = icmp sgt i32 %x, %y
315 br i1 %cmp, label %t, label %f
319 %cmp2 = icmp sge i32 %y, %x