xref: /llvm-project/llvm/test/Transforms/InstCombine/cast_phi.ll (revision 23a239267e8a1d20ed10d3545feaf2a2bb70b085)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4target datalayout = "n32:64"
5
6define void @MainKernel(i32 %iNumSteps, i32 %tid, i32 %base) {
7; CHECK-LABEL: @MainKernel(
8; CHECK-NEXT:    [[CALLA:%.*]] = alloca [258 x float], align 4
9; CHECK-NEXT:    [[CALLB:%.*]] = alloca [258 x float], align 4
10; CHECK-NEXT:    [[CONV_I:%.*]] = uitofp i32 [[INUMSTEPS:%.*]] to float
11; CHECK-NEXT:    [[CONV_I12:%.*]] = zext i32 [[TID:%.*]] to i64
12; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [258 x float], ptr [[CALLA]], i64 0, i64 [[CONV_I12]]
13; CHECK-NEXT:    store float [[CONV_I]], ptr [[ARRAYIDX3]], align 4
14; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [258 x float], ptr [[CALLB]], i64 0, i64 [[CONV_I12]]
15; CHECK-NEXT:    store float [[CONV_I]], ptr [[ARRAYIDX6]], align 4
16; CHECK-NEXT:    [[CMP7:%.*]] = icmp eq i32 [[TID]], 0
17; CHECK-NEXT:    br i1 [[CMP7]], label [[DOTBB1:%.*]], label [[DOTBB2:%.*]]
18; CHECK:       .bb1:
19; CHECK-NEXT:    [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLA]], i64 1024
20; CHECK-NEXT:    store float [[CONV_I]], ptr [[ARRAYIDX10]], align 4
21; CHECK-NEXT:    [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLB]], i64 1024
22; CHECK-NEXT:    store float 0.000000e+00, ptr [[ARRAYIDX11]], align 4
23; CHECK-NEXT:    br label [[DOTBB2]]
24; CHECK:       .bb2:
25; CHECK-NEXT:    [[CMP135:%.*]] = icmp sgt i32 [[INUMSTEPS]], 0
26; CHECK-NEXT:    br i1 [[CMP135]], label [[DOTBB3:%.*]], label [[DOTBB8:%.*]]
27; CHECK:       .bb3:
28; CHECK-NEXT:    [[TMP1:%.*]] = phi float [ [[TMP10:%.*]], [[DOTBB12:%.*]] ], [ [[CONV_I]], [[DOTBB2]] ]
29; CHECK-NEXT:    [[TMP2:%.*]] = phi float [ [[TMP11:%.*]], [[DOTBB12]] ], [ [[CONV_I]], [[DOTBB2]] ]
30; CHECK-NEXT:    [[I12_06:%.*]] = phi i32 [ [[SUB:%.*]], [[DOTBB12]] ], [ [[INUMSTEPS]], [[DOTBB2]] ]
31; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[I12_06]], [[BASE:%.*]]
32; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[I12_06]], 1
33; CHECK-NEXT:    [[CONV_I9:%.*]] = sext i32 [[ADD]] to i64
34; CHECK-NEXT:    [[ARRAYIDX20:%.*]] = getelementptr inbounds [258 x float], ptr [[CALLA]], i64 0, i64 [[CONV_I9]]
35; CHECK-NEXT:    [[ARRAYIDX24:%.*]] = getelementptr inbounds [258 x float], ptr [[CALLB]], i64 0, i64 [[CONV_I9]]
36; CHECK-NEXT:    [[CMP40:%.*]] = icmp ult i32 [[I12_06]], [[BASE]]
37; CHECK-NEXT:    br i1 [[TMP3]], label [[DOTBB4:%.*]], label [[DOTBB5:%.*]]
38; CHECK:       .bb4:
39; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[ARRAYIDX20]], align 4
40; CHECK-NEXT:    [[TMP5:%.*]] = load float, ptr [[ARRAYIDX24]], align 4
41; CHECK-NEXT:    [[ADD33:%.*]] = fadd float [[TMP5]], [[TMP4]]
42; CHECK-NEXT:    [[ADD33_1:%.*]] = fadd float [[ADD33]], [[TMP1]]
43; CHECK-NEXT:    [[ADD33_2:%.*]] = fadd float [[ADD33_1]], [[TMP2]]
44; CHECK-NEXT:    br label [[DOTBB5]]
45; CHECK:       .bb5:
46; CHECK-NEXT:    [[TMP6:%.*]] = phi float [ [[ADD33_1]], [[DOTBB4]] ], [ [[TMP1]], [[DOTBB3]] ]
47; CHECK-NEXT:    [[TMP7:%.*]] = phi float [ [[ADD33_2]], [[DOTBB4]] ], [ [[TMP2]], [[DOTBB3]] ]
48; CHECK-NEXT:    br i1 [[CMP40]], label [[DOTBB6:%.*]], label [[DOTBB7:%.*]]
49; CHECK:       .bb6:
50; CHECK-NEXT:    store float [[TMP7]], ptr [[ARRAYIDX3]], align 4
51; CHECK-NEXT:    store float [[TMP6]], ptr [[ARRAYIDX6]], align 4
52; CHECK-NEXT:    br label [[DOTBB7]]
53; CHECK:       .bb7:
54; CHECK-NEXT:    br i1 [[TMP3]], label [[DOTBB9:%.*]], label [[DOTBB10:%.*]]
55; CHECK:       .bb8:
56; CHECK-NEXT:    ret void
57; CHECK:       .bb9:
58; CHECK-NEXT:    [[TMP8:%.*]] = load float, ptr [[ARRAYIDX20]], align 4
59; CHECK-NEXT:    [[TMP9:%.*]] = load float, ptr [[ARRAYIDX24]], align 4
60; CHECK-NEXT:    [[ADD33_112:%.*]] = fadd float [[TMP9]], [[TMP8]]
61; CHECK-NEXT:    [[ADD33_1_1:%.*]] = fadd float [[ADD33_112]], [[TMP6]]
62; CHECK-NEXT:    [[ADD33_2_1:%.*]] = fadd float [[ADD33_1_1]], [[TMP7]]
63; CHECK-NEXT:    br label [[DOTBB10]]
64; CHECK:       .bb10:
65; CHECK-NEXT:    [[TMP10]] = phi float [ [[ADD33_1_1]], [[DOTBB9]] ], [ [[TMP6]], [[DOTBB7]] ]
66; CHECK-NEXT:    [[TMP11]] = phi float [ [[ADD33_2_1]], [[DOTBB9]] ], [ [[TMP7]], [[DOTBB7]] ]
67; CHECK-NEXT:    br i1 [[CMP40]], label [[DOTBB11:%.*]], label [[DOTBB12]]
68; CHECK:       .bb11:
69; CHECK-NEXT:    store float [[TMP11]], ptr [[ARRAYIDX3]], align 4
70; CHECK-NEXT:    store float [[TMP10]], ptr [[ARRAYIDX6]], align 4
71; CHECK-NEXT:    br label [[DOTBB12]]
72; CHECK:       .bb12:
73; CHECK-NEXT:    [[SUB]] = add nsw i32 [[I12_06]], -4
74; CHECK-NEXT:    [[CMP13:%.*]] = icmp sgt i32 [[I12_06]], 4
75; CHECK-NEXT:    br i1 [[CMP13]], label [[DOTBB3]], label [[DOTBB8]]
76;
77  %callA = alloca [258 x float], align 4
78  %callB = alloca [258 x float], align 4
79  %conv.i = uitofp i32 %iNumSteps to float
80  %1 = bitcast float %conv.i to i32
81  %conv.i12 = zext i32 %tid to i64
82  %arrayidx3 = getelementptr inbounds [258 x float], ptr %callA, i64 0, i64 %conv.i12
83  store i32 %1, ptr %arrayidx3, align 4
84  %arrayidx6 = getelementptr inbounds [258 x float], ptr %callB, i64 0, i64 %conv.i12
85  store i32 %1, ptr %arrayidx6, align 4
86  %cmp7 = icmp eq i32 %tid, 0
87  br i1 %cmp7, label %.bb1, label %.bb2
88
89.bb1:
90  %arrayidx10 = getelementptr inbounds [258 x float], ptr %callA, i64 0, i64 256
91  store float %conv.i, ptr %arrayidx10, align 4
92  %arrayidx11 = getelementptr inbounds [258 x float], ptr %callB, i64 0, i64 256
93  store float 0.000000e+00, ptr %arrayidx11, align 4
94  br label %.bb2
95
96.bb2:
97  %cmp135 = icmp sgt i32 %iNumSteps, 0
98  br i1 %cmp135, label %.bb3, label %.bb8
99
100.bb3:
101  %rA.sroa.8.0 = phi i32 [ %rA.sroa.8.2, %.bb12 ], [ %1, %.bb2 ]
102  %rA.sroa.0.0 = phi i32 [ %rA.sroa.0.2, %.bb12 ], [ %1, %.bb2 ]
103  %i12.06 = phi i32 [ %sub, %.bb12 ], [ %iNumSteps, %.bb2 ]
104  %2 = icmp ugt i32 %i12.06, %base
105  %add = add i32 %i12.06, 1
106  %conv.i9 = sext i32 %add to i64
107  %arrayidx20 = getelementptr inbounds [258 x float], ptr %callA, i64 0, i64 %conv.i9
108  %arrayidx24 = getelementptr inbounds [258 x float], ptr %callB, i64 0, i64 %conv.i9
109  %cmp40 = icmp ult i32 %i12.06, %base
110  br i1 %2, label %.bb4, label %.bb5
111
112.bb4:
113  %3 = load i32, ptr %arrayidx20, align 4
114  %4 = load i32, ptr %arrayidx24, align 4
115  %5 = bitcast i32 %4 to float
116  %6 = bitcast i32 %3 to float
117  %add33 = fadd float %5, %6
118  %7 = bitcast i32 %rA.sroa.8.0 to float
119  %add33.1 = fadd float %add33, %7
120  %8 = bitcast float %add33.1 to i32
121  %9 = bitcast i32 %rA.sroa.0.0 to float
122  %add33.2 = fadd float %add33.1, %9
123  %10 = bitcast float %add33.2 to i32
124  br label %.bb5
125
126.bb5:
127  %rA.sroa.8.1 = phi i32 [ %8, %.bb4 ], [ %rA.sroa.8.0, %.bb3 ]
128  %rA.sroa.0.1 = phi i32 [ %10, %.bb4 ], [ %rA.sroa.0.0, %.bb3 ]
129  br i1 %cmp40, label %.bb6, label %.bb7
130
131.bb6:
132  store i32 %rA.sroa.0.1, ptr %arrayidx3, align 4
133  store i32 %rA.sroa.8.1, ptr %arrayidx6, align 4
134  br label %.bb7
135
136.bb7:
137  br i1 %2, label %.bb9, label %.bb10
138
139.bb8:
140  ret void
141
142.bb9:
143  %11 = load i32, ptr %arrayidx20, align 4
144  %12 = load i32, ptr %arrayidx24, align 4
145  %13 = bitcast i32 %12 to float
146  %14 = bitcast i32 %11 to float
147  %add33.112 = fadd float %13, %14
148  %15 = bitcast i32 %rA.sroa.8.1 to float
149  %add33.1.1 = fadd float %add33.112, %15
150  %16 = bitcast float %add33.1.1 to i32
151  %17 = bitcast i32 %rA.sroa.0.1 to float
152  %add33.2.1 = fadd float %add33.1.1, %17
153  %18 = bitcast float %add33.2.1 to i32
154  br label %.bb10
155
156.bb10:
157  %rA.sroa.8.2 = phi i32 [ %16, %.bb9 ], [ %rA.sroa.8.1, %.bb7 ]
158  %rA.sroa.0.2 = phi i32 [ %18, %.bb9 ], [ %rA.sroa.0.1, %.bb7 ]
159  br i1 %cmp40, label %.bb11, label %.bb12
160
161.bb11:
162  store i32 %rA.sroa.0.2, ptr %arrayidx3, align 4
163  store i32 %rA.sroa.8.2, ptr %arrayidx6, align 4
164  br label %.bb12
165
166.bb12:
167  %sub = add i32 %i12.06, -4
168  %cmp13 = icmp sgt i32 %sub, 0
169  br i1 %cmp13, label %.bb3, label %.bb8
170}
171
172declare i32 @get_i32()
173declare i3 @get_i3()
174declare void @bar()
175
176define i37 @zext_from_legal_to_illegal_type(i32 %x) {
177; CHECK-LABEL: @zext_from_legal_to_illegal_type(
178; CHECK-NEXT:  entry:
179; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42
180; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
181; CHECK:       t:
182; CHECK-NEXT:    [[Y:%.*]] = call i32 @get_i32()
183; CHECK-NEXT:    br label [[EXIT:%.*]]
184; CHECK:       f:
185; CHECK-NEXT:    call void @bar()
186; CHECK-NEXT:    br label [[EXIT]]
187; CHECK:       exit:
188; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[Y]], [[T]] ], [ 3, [[F]] ]
189; CHECK-NEXT:    [[R:%.*]] = zext i32 [[P]] to i37
190; CHECK-NEXT:    ret i37 [[R]]
191;
192entry:
193  %cmp = icmp eq i32 %x, 42
194  br i1 %cmp, label %t, label %f
195
196t:
197  %y = call i32 @get_i32()
198  br label %exit
199
200f:
201  call void @bar()
202  br label %exit
203
204exit:
205  %p = phi i32 [ %y, %t ], [ 3, %f ]
206  %r = zext i32 %p to i37
207  ret i37 %r
208}
209
210define i37 @zext_from_illegal_to_illegal_type(i32 %x) {
211; CHECK-LABEL: @zext_from_illegal_to_illegal_type(
212; CHECK-NEXT:  entry:
213; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42
214; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
215; CHECK:       t:
216; CHECK-NEXT:    [[Y:%.*]] = call i3 @get_i3()
217; CHECK-NEXT:    br label [[EXIT:%.*]]
218; CHECK:       f:
219; CHECK-NEXT:    call void @bar()
220; CHECK-NEXT:    br label [[EXIT]]
221; CHECK:       exit:
222; CHECK-NEXT:    [[P:%.*]] = phi i3 [ [[Y]], [[T]] ], [ 3, [[F]] ]
223; CHECK-NEXT:    [[R:%.*]] = zext i3 [[P]] to i37
224; CHECK-NEXT:    ret i37 [[R]]
225;
226entry:
227  %cmp = icmp eq i32 %x, 42
228  br i1 %cmp, label %t, label %f
229
230t:
231  %y = call i3 @get_i3()
232  br label %exit
233
234f:
235  call void @bar()
236  br label %exit
237
238exit:
239  %p = phi i3 [ %y, %t ], [ 3, %f ]
240  %r = zext i3 %p to i37
241  ret i37 %r
242}
243
244define i64 @zext_from_legal_to_legal_type(i32 %x) {
245; CHECK-LABEL: @zext_from_legal_to_legal_type(
246; CHECK-NEXT:  entry:
247; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42
248; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
249; CHECK:       t:
250; CHECK-NEXT:    [[Y:%.*]] = call i32 @get_i32()
251; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[Y]] to i64
252; CHECK-NEXT:    br label [[EXIT:%.*]]
253; CHECK:       f:
254; CHECK-NEXT:    call void @bar()
255; CHECK-NEXT:    br label [[EXIT]]
256; CHECK:       exit:
257; CHECK-NEXT:    [[P:%.*]] = phi i64 [ [[TMP0]], [[T]] ], [ 3, [[F]] ]
258; CHECK-NEXT:    ret i64 [[P]]
259;
260entry:
261  %cmp = icmp eq i32 %x, 42
262  br i1 %cmp, label %t, label %f
263
264t:
265  %y = call i32 @get_i32()
266  br label %exit
267
268f:
269  call void @bar()
270  br label %exit
271
272exit:
273  %p = phi i32 [ %y, %t ], [ 3, %f ]
274  %r = zext i32 %p to i64
275  ret i64 %r
276}
277
278define i64 @zext_from_illegal_to_legal_type(i32 %x) {
279; CHECK-LABEL: @zext_from_illegal_to_legal_type(
280; CHECK-NEXT:  entry:
281; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42
282; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
283; CHECK:       t:
284; CHECK-NEXT:    [[Y:%.*]] = call i3 @get_i3()
285; CHECK-NEXT:    [[TMP0:%.*]] = zext i3 [[Y]] to i64
286; CHECK-NEXT:    br label [[EXIT:%.*]]
287; CHECK:       f:
288; CHECK-NEXT:    call void @bar()
289; CHECK-NEXT:    br label [[EXIT]]
290; CHECK:       exit:
291; CHECK-NEXT:    [[P:%.*]] = phi i64 [ [[TMP0]], [[T]] ], [ 3, [[F]] ]
292; CHECK-NEXT:    ret i64 [[P]]
293;
294entry:
295  %cmp = icmp eq i32 %x, 42
296  br i1 %cmp, label %t, label %f
297
298t:
299  %y = call i3 @get_i3()
300  br label %exit
301
302f:
303  call void @bar()
304  br label %exit
305
306exit:
307  %p = phi i3 [ %y, %t ], [ 3, %f ]
308  %r = zext i3 %p to i64
309  ret i64 %r
310}
311
312define i8 @trunc_in_loop_exit_block() {
313; CHECK-LABEL: @trunc_in_loop_exit_block(
314; CHECK-NEXT:  entry:
315; CHECK-NEXT:    br label [[LOOP:%.*]]
316; CHECK:       loop:
317; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
318; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_NEXT]], [[LOOP_LATCH]] ]
319; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[IV]], 100
320; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
321; CHECK:       loop.latch:
322; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
323; CHECK-NEXT:    br label [[LOOP]]
324; CHECK:       exit:
325; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[PHI]] to i8
326; CHECK-NEXT:    ret i8 [[TRUNC]]
327;
328entry:
329  br label %loop
330
331loop:
332  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
333  %phi = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
334  %cmp = icmp ult i32 %iv, 100
335  br i1 %cmp, label %loop.latch, label %exit
336
337loop.latch:
338  %iv.next = add i32 %iv, 1
339  br label %loop
340
341exit:
342  %trunc = trunc i32 %phi to i8
343  ret i8 %trunc
344}
345
346define i32 @zext_in_loop_and_exit_block(i8 %step, i32 %end) {
347; CHECK-LABEL: @zext_in_loop_and_exit_block(
348; CHECK-NEXT:  entry:
349; CHECK-NEXT:    br label [[LOOP:%.*]]
350; CHECK:       loop:
351; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
352; CHECK-NEXT:    [[IV_EXT:%.*]] = zext i8 [[IV]] to i32
353; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[END:%.*]], [[IV_EXT]]
354; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
355; CHECK:       loop.latch:
356; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], [[STEP:%.*]]
357; CHECK-NEXT:    br label [[LOOP]]
358; CHECK:       exit:
359; CHECK-NEXT:    [[EXT:%.*]] = zext i8 [[IV]] to i32
360; CHECK-NEXT:    ret i32 [[EXT]]
361;
362entry:
363  br label %loop
364
365loop:
366  %iv = phi i8 [ 0, %entry ], [ %iv.next.trunc, %loop.latch ]
367  %iv.ext = zext i8 %iv to i32
368  %cmp = icmp ne i32 %iv.ext, %end
369  br i1 %cmp, label %loop.latch, label %exit
370
371loop.latch:
372  %step.ext = zext i8 %step to i32
373  %iv.next = add i32 %iv.ext, %step.ext
374  %iv.next.trunc = trunc i32 %iv.next to i8
375  br label %loop
376
377exit:
378  %ext = zext i8 %iv to i32
379  ret i32 %ext
380}
381