[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / InstCombine / merging-multiple-stores-into-successor.ll
blob41e3197e5a2f0bb519db282d36a9c7ff3effbca4
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 target datalayout = "n32"
6 @var_7 = external global i8, align 1
7 @var_1 = external global i32, align 4
8 @var_0 = external global i16, align 2
9 @var_5 = external global i64, align 8
10 @arr_2 = external global [0 x i32], align 4
11 @arr_4 = external global [0 x i16], align 2
12 @arr_3 = external global [8 x i32], align 16
14 define void @_Z4testv() {
15 ; CHECK-LABEL: @_Z4testv(
16 ; CHECK-NEXT:  bb:
17 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr @var_7, align 1
18 ; CHECK-NEXT:    [[I1:%.*]] = icmp eq i8 [[I]], -1
19 ; CHECK-NEXT:    [[I4:%.*]] = load i16, ptr @var_0, align 2
20 ; CHECK-NEXT:    br i1 [[I1]], label [[BB10:%.*]], label [[BB9:%.*]]
21 ; CHECK:       bb9:
22 ; CHECK-NEXT:    br label [[BB12:%.*]]
23 ; CHECK:       bb10:
24 ; CHECK-NEXT:    [[I2:%.*]] = load i32, ptr @var_1, align 4
25 ; CHECK-NEXT:    [[I3:%.*]] = icmp eq i32 [[I2]], 0
26 ; CHECK-NEXT:    [[I6:%.*]] = load i64, ptr @var_5, align 8
27 ; CHECK-NEXT:    [[I5:%.*]] = sext i16 [[I4]] to i64
28 ; CHECK-NEXT:    [[I7:%.*]] = select i1 [[I3]], i64 [[I6]], i64 [[I5]]
29 ; CHECK-NEXT:    [[I11:%.*]] = trunc i64 [[I7]] to i32
30 ; CHECK-NEXT:    br label [[BB12]]
31 ; CHECK:       bb12:
32 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ 1, [[BB9]] ], [ [[I11]], [[BB10]] ]
33 ; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr @arr_2, align 4
34 ; CHECK-NEXT:    store i16 [[I4]], ptr @arr_4, align 2
35 ; CHECK-NEXT:    [[I8:%.*]] = sext i16 [[I4]] to i32
36 ; CHECK-NEXT:    store i32 [[I8]], ptr @arr_3, align 4
37 ; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr getelementptr inbounds (i8, ptr @arr_2, i64 4), align 4
38 ; CHECK-NEXT:    store i16 [[I4]], ptr getelementptr inbounds (i8, ptr @arr_4, i64 2), align 2
39 ; CHECK-NEXT:    store i32 [[I8]], ptr getelementptr inbounds (i8, ptr @arr_3, i64 4), align 4
40 ; CHECK-NEXT:    ret void
42 bb:
43   %i = load i8, ptr @var_7, align 1
44   %i1 = icmp eq i8 %i, -1
45   %i2 = load i32, ptr @var_1, align 4
46   %i3 = icmp eq i32 %i2, 0
47   %i4 = load i16, ptr @var_0, align 2
48   %i5 = sext i16 %i4 to i64
49   %i6 = load i64, ptr @var_5, align 8
50   %i7 = select i1 %i3, i64 %i6, i64 %i5
51   %i8 = sext i16 %i4 to i32
52   br i1 %i1, label %bb10, label %bb9
54 bb9:                                              ; preds = %bb
55   store i32 1, ptr @arr_2, align 4
56   store i16 %i4, ptr @arr_4, align 2
57   store i32 %i8, ptr @arr_3, align 4
58   store i32 1, ptr getelementptr inbounds ([0 x i32], ptr @arr_2, i64 0, i64 1), align 4
59   store i16 %i4, ptr getelementptr inbounds ([0 x i16], ptr @arr_4, i64 0, i64 1), align 2
60   store i32 %i8, ptr getelementptr inbounds ([8 x i32], ptr @arr_3, i64 0, i64 1), align 4
61   br label %bb12
63 bb10:                                             ; preds = %bb
64   %i11 = trunc i64 %i7 to i32
65   store i32 %i11, ptr @arr_2, align 4
66   store i16 %i4, ptr @arr_4, align 2
67   store i32 %i8, ptr @arr_3, align 4
68   store i32 %i11, ptr getelementptr inbounds ([0 x i32], ptr @arr_2, i64 0, i64 1), align 4
69   store i16 %i4, ptr getelementptr inbounds ([0 x i16], ptr @arr_4, i64 0, i64 1), align 2
70   store i32 %i8, ptr getelementptr inbounds ([8 x i32], ptr @arr_3, i64 0, i64 1), align 4
71   br label %bb12
73 bb12:                                             ; preds = %bb10, %bb9
74   ret void
77 define half @diff_types_same_width_merge(i1 %cond, half %a, i16 %b) {
78 ; CHECK-LABEL: @diff_types_same_width_merge(
79 ; CHECK-NEXT:  entry:
80 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
81 ; CHECK:       BB0:
82 ; CHECK-NEXT:    br label [[SINK:%.*]]
83 ; CHECK:       BB1:
84 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16 [[B:%.*]] to half
85 ; CHECK-NEXT:    br label [[SINK]]
86 ; CHECK:       sink:
87 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi half [ [[TMP0]], [[BB1]] ], [ [[A:%.*]], [[BB0]] ]
88 ; CHECK-NEXT:    ret half [[STOREMERGE]]
90 entry:
91   %alloca = alloca half
92   br i1 %cond, label %BB0, label %BB1
93 BB0:
94   store half %a, ptr %alloca
95   br label %sink
96 BB1:
97   store i16 %b, ptr %alloca
98   br label %sink
99 sink:
100   %val = load half, ptr %alloca
101   ret half %val
104 define i32 @diff_types_diff_width_no_merge(i1 %cond, i32 %a, i64 %b) {
105 ; CHECK-LABEL: @diff_types_diff_width_no_merge(
106 ; CHECK-NEXT:  entry:
107 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca i64, align 8
108 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
109 ; CHECK:       if:
110 ; CHECK-NEXT:    store i32 [[A:%.*]], ptr [[ALLOCA]], align 4
111 ; CHECK-NEXT:    br label [[SINK:%.*]]
112 ; CHECK:       else:
113 ; CHECK-NEXT:    store i64 [[B:%.*]], ptr [[ALLOCA]], align 4
114 ; CHECK-NEXT:    br label [[SINK]]
115 ; CHECK:       sink:
116 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[ALLOCA]], align 4
117 ; CHECK-NEXT:    ret i32 [[VAL]]
119 entry:
120   %alloca = alloca i64
121   br i1 %cond, label %if, label %else
123   store i32 %a, ptr %alloca
124   br label %sink
125   else:
126   store i64 %b, ptr %alloca
127   br label %sink
128 sink:
129   %val = load i32, ptr %alloca
130   ret i32 %val
133 define <4 x i32> @vec_no_merge(i1 %cond, <2 x i32> %a, <4 x i32> %b) {
134 ; CHECK-LABEL: @vec_no_merge(
135 ; CHECK-NEXT:  entry:
136 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca i64, align 8
137 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
138 ; CHECK:       if:
139 ; CHECK-NEXT:    store <2 x i32> [[A:%.*]], ptr [[ALLOCA]], align 8
140 ; CHECK-NEXT:    br label [[SINK:%.*]]
141 ; CHECK:       else:
142 ; CHECK-NEXT:    store <4 x i32> [[B:%.*]], ptr [[ALLOCA]], align 16
143 ; CHECK-NEXT:    br label [[SINK]]
144 ; CHECK:       sink:
145 ; CHECK-NEXT:    [[VAL:%.*]] = load <4 x i32>, ptr [[ALLOCA]], align 16
146 ; CHECK-NEXT:    ret <4 x i32> [[VAL]]
148 entry:
149   %alloca = alloca i64
150   br i1 %cond, label %if, label %else
152   store <2 x i32> %a, ptr %alloca
153   br label %sink
154 else:
155   store <4 x i32> %b, ptr %alloca
156   br label %sink
157 sink:
158   %val = load <4 x i32>, ptr %alloca
159   ret <4 x i32> %val
162 %struct.half = type { half };
164 define %struct.half @one_elem_struct_merge(i1 %cond, %struct.half %a, half %b) {
165 ; CHECK-LABEL: @one_elem_struct_merge(
166 ; CHECK-NEXT:  entry:
167 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
168 ; CHECK:       BB0:
169 ; CHECK-NEXT:    br label [[SINK:%.*]]
170 ; CHECK:       BB1:
171 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue [[STRUCT_HALF:%.*]] poison, half [[B:%.*]], 0
172 ; CHECK-NEXT:    br label [[SINK]]
173 ; CHECK:       sink:
174 ; CHECK-NEXT:    [[VAL1_MERGED:%.*]] = phi [[STRUCT_HALF]] [ [[A:%.*]], [[BB0]] ], [ [[TMP0]], [[BB1]] ]
175 ; CHECK-NEXT:    ret [[STRUCT_HALF]] [[VAL1_MERGED]]
177 entry:
178   %alloca = alloca i64
179   br i1 %cond, label %BB0, label %BB1
180 BB0:
181   store %struct.half %a, ptr %alloca
182   br label %sink
183 BB1:
184   store half %b, ptr %alloca
185   br label %sink
186 sink:
187   %val = load %struct.half, ptr %alloca
188   ret %struct.half %val
191 %struct.tup = type { half, i32 };
193 define %struct.tup @multi_elem_struct_no_merge(i1 %cond, %struct.tup %a, half %b) {
194 ; CHECK-LABEL: @multi_elem_struct_no_merge(
195 ; CHECK-NEXT:  entry:
196 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca i64, align 8
197 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
198 ; CHECK:       if:
199 ; CHECK-NEXT:    store [[STRUCT_TUP:%.*]] [[A:%.*]], ptr [[ALLOCA]], align 4
200 ; CHECK-NEXT:    br label [[SINK:%.*]]
201 ; CHECK:       else:
202 ; CHECK-NEXT:    store half [[B:%.*]], ptr [[ALLOCA]], align 2
203 ; CHECK-NEXT:    br label [[SINK]]
204 ; CHECK:       sink:
205 ; CHECK-NEXT:    [[VAL:%.*]] = load [[STRUCT_TUP]], ptr [[ALLOCA]], align 4
206 ; CHECK-NEXT:    ret [[STRUCT_TUP]] [[VAL]]
208 entry:
209   %alloca = alloca i64
210   br i1 %cond, label %if, label %else
212   store %struct.tup %a, ptr %alloca
213   br label %sink
214 else:
215   store half %b, ptr %alloca
216   br label %sink
217 sink:
218   %val = load %struct.tup, ptr %alloca
219   ret %struct.tup %val
222 define i16 @same_types_diff_align_no_merge(i1 %cond, i16 %a, i16 %b) {
223 ; CHECK-LABEL: @same_types_diff_align_no_merge(
224 ; CHECK-NEXT:  entry:
225 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca i16, align 4
226 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
227 ; CHECK:       BB0:
228 ; CHECK-NEXT:    store i16 [[A:%.*]], ptr [[ALLOCA]], align 8
229 ; CHECK-NEXT:    br label [[SINK:%.*]]
230 ; CHECK:       BB1:
231 ; CHECK-NEXT:    store i16 [[B:%.*]], ptr [[ALLOCA]], align 4
232 ; CHECK-NEXT:    br label [[SINK]]
233 ; CHECK:       sink:
234 ; CHECK-NEXT:    [[VAL:%.*]] = load i16, ptr [[ALLOCA]], align 2
235 ; CHECK-NEXT:    ret i16 [[VAL]]
237 entry:
238   %alloca = alloca i16, align 4
239   br i1 %cond, label %BB0, label %BB1
240 BB0:
241   store i16 %a, ptr %alloca, align 8
242   br label %sink
243 BB1:
244   store i16 %b, ptr %alloca, align 4
245   br label %sink
246 sink:
247   %val = load i16, ptr %alloca
248   ret i16 %val
251 define i64 @ptrtoint_merge(i1 %cond, i64 %a, ptr %b) {
252 ; CHECK-LABEL: @ptrtoint_merge(
253 ; CHECK-NEXT:  entry:
254 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8
255 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
256 ; CHECK:       BB0:
257 ; CHECK-NEXT:    store i64 [[A:%.*]], ptr [[ALLOCA]], align 4
258 ; CHECK-NEXT:    br label [[SINK:%.*]]
259 ; CHECK:       BB1:
260 ; CHECK-NEXT:    store ptr [[B:%.*]], ptr [[ALLOCA]], align 8
261 ; CHECK-NEXT:    br label [[SINK]]
262 ; CHECK:       sink:
263 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[ALLOCA]], align 4
264 ; CHECK-NEXT:    ret i64 [[VAL]]
266 entry:
267   %alloca = alloca ptr
268   br i1 %cond, label %BB0, label %BB1
269 BB0:
270   store i64 %a, ptr %alloca
271   br label %sink
272 BB1:
273   store ptr %b, ptr %alloca
274   br label %sink
275 sink:
276   %val = load i64, ptr %alloca
277   ret i64 %val
280 define ptr @inttoptr_merge(i1 %cond, i64 %a, ptr %b) {
281 ; CHECK-LABEL: @inttoptr_merge(
282 ; CHECK-NEXT:  entry:
283 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
284 ; CHECK:       BB0:
285 ; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[A:%.*]] to ptr
286 ; CHECK-NEXT:    br label [[SINK:%.*]]
287 ; CHECK:       BB1:
288 ; CHECK-NEXT:    br label [[SINK]]
289 ; CHECK:       sink:
290 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi ptr [ [[B:%.*]], [[BB1]] ], [ [[TMP0]], [[BB0]] ]
291 ; CHECK-NEXT:    ret ptr [[STOREMERGE]]
293 entry:
294   %alloca = alloca ptr
295   br i1 %cond, label %BB0, label %BB1
296 BB0:
297   store i64 %a, ptr %alloca, align 8
298   br label %sink
299 BB1:
300   store ptr %b, ptr %alloca, align 8
301   br label %sink
302 sink:
303   %val = load ptr, ptr %alloca
304   ret ptr %val
308 define void @pr46688(i1 %cond, i32 %x, i16 %d, ptr %p1, ptr %p2) {
309 ; CHECK-LABEL: @pr46688(
310 ; CHECK-NEXT:  entry:
311 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
312 ; CHECK:       if:
313 ; CHECK-NEXT:    br label [[EXIT:%.*]]
314 ; CHECK:       else:
315 ; CHECK-NEXT:    br label [[EXIT]]
316 ; CHECK:       exit:
317 ; CHECK-NEXT:    [[DONV_PN:%.*]] = zext i16 [[D:%.*]] to i32
318 ; CHECK-NEXT:    [[THR_PN:%.*]] = lshr i32 [[DONV_PN]], [[X:%.*]]
319 ; CHECK-NEXT:    [[THR1_PN:%.*]] = lshr i32 [[THR_PN]], [[X]]
320 ; CHECK-NEXT:    [[THR2_PN:%.*]] = lshr i32 [[THR1_PN]], [[X]]
321 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = lshr i32 [[THR2_PN]], [[X]]
322 ; CHECK-NEXT:    [[STOREMERGE1:%.*]] = trunc nuw i32 [[STOREMERGE]] to i16
323 ; CHECK-NEXT:    store i16 [[STOREMERGE1]], ptr [[P1:%.*]], align 2
324 ; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[P2:%.*]], align 4
325 ; CHECK-NEXT:    ret void
327 entry:
328   br i1 %cond, label %if, label %else
331   %conv = zext i16 %d to i32
332   %shr = lshr i32 %conv, %x
333   %shr1 = lshr i32 %shr, %x
334   %shr2 = lshr i32 %shr1, %x
335   %shr3 = lshr i32 %shr2, %x
336   %conv4 = trunc i32 %shr3 to i16
337   store i16 %conv4, ptr %p1, align 2
338   %conv5 = and i32 %shr3, 65535
339   store i32 %conv5, ptr %p2, align 4
340   br label %exit
342 else:
343   %donv = zext i16 %d to i32
344   %thr = lshr i32 %donv, %x
345   %thr1 = lshr i32 %thr, %x
346   %thr2 = lshr i32 %thr1, %x
347   %thr3 = lshr i32 %thr2, %x
348   %donv4 = trunc i32 %thr3 to i16
349   store i16 %donv4, ptr %p1, align 2
350   store i32 %thr3, ptr %p2, align 4
351   br label %exit
353 exit:
354   ret void