1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -O2 -expand-reductions -S < %s | FileCheck %s
3
4; Test if SLP vector reduction patterns are recognized
5; and optionally converted to reduction intrinsics and
6; back to raw IR.
7
8target triple = "x86_64--"
9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10
11define i32 @add_v4i32(i32* %p) #0 {
12; CHECK-LABEL: @add_v4i32(
13; CHECK-NEXT:  entry:
14; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>*
15; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4, !tbaa !0
16; CHECK-NEXT:    [[RDX_SHUF:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
17; CHECK-NEXT:    [[BIN_RDX:%.*]] = add <4 x i32> [[TMP1]], [[RDX_SHUF]]
18; CHECK-NEXT:    [[RDX_SHUF3:%.*]] = shufflevector <4 x i32> [[BIN_RDX]], <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
19; CHECK-NEXT:    [[BIN_RDX4:%.*]] = add <4 x i32> [[BIN_RDX]], [[RDX_SHUF3]]
20; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i32> [[BIN_RDX4]], i32 0
21; CHECK-NEXT:    ret i32 [[TMP2]]
22;
23entry:
24  br label %for.cond
25
26for.cond:
27  %r.0 = phi i32 [ 0, %entry ], [ %add, %for.inc ]
28  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
29  %cmp = icmp slt i32 %i.0, 4
30  br i1 %cmp, label %for.body, label %for.cond.cleanup
31
32for.cond.cleanup:
33  br label %for.end
34
35for.body:
36  %idxprom = sext i32 %i.0 to i64
37  %arrayidx = getelementptr inbounds i32, i32* %p, i64 %idxprom
38  %0 = load i32, i32* %arrayidx, align 4, !tbaa !3
39  %add = add nsw i32 %r.0, %0
40  br label %for.inc
41
42for.inc:
43  %inc = add nsw i32 %i.0, 1
44  br label %for.cond
45
46for.end:
47  ret i32 %r.0
48}
49
50define signext i16 @mul_v8i16(i16* %p) #0 {
51; CHECK-LABEL: @mul_v8i16(
52; CHECK-NEXT:  entry:
53; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[P:%.*]] to <8 x i16>*
54; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2, !tbaa !4
55; CHECK-NEXT:    [[RDX_SHUF:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
56; CHECK-NEXT:    [[BIN_RDX:%.*]] = mul <8 x i16> [[TMP1]], [[RDX_SHUF]]
57; CHECK-NEXT:    [[RDX_SHUF3:%.*]] = shufflevector <8 x i16> [[BIN_RDX]], <8 x i16> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
58; CHECK-NEXT:    [[BIN_RDX4:%.*]] = mul <8 x i16> [[BIN_RDX]], [[RDX_SHUF3]]
59; CHECK-NEXT:    [[RDX_SHUF5:%.*]] = shufflevector <8 x i16> [[BIN_RDX4]], <8 x i16> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
60; CHECK-NEXT:    [[BIN_RDX6:%.*]] = mul <8 x i16> [[BIN_RDX4]], [[RDX_SHUF5]]
61; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <8 x i16> [[BIN_RDX6]], i32 0
62; CHECK-NEXT:    ret i16 [[TMP2]]
63;
64entry:
65  br label %for.cond
66
67for.cond:
68  %r.0 = phi i16 [ 1, %entry ], [ %conv2, %for.inc ]
69  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
70  %cmp = icmp slt i32 %i.0, 8
71  br i1 %cmp, label %for.body, label %for.cond.cleanup
72
73for.cond.cleanup:
74  br label %for.end
75
76for.body:
77  %idxprom = sext i32 %i.0 to i64
78  %arrayidx = getelementptr inbounds i16, i16* %p, i64 %idxprom
79  %0 = load i16, i16* %arrayidx, align 2, !tbaa !7
80  %conv = sext i16 %0 to i32
81  %conv1 = sext i16 %r.0 to i32
82  %mul = mul nsw i32 %conv1, %conv
83  %conv2 = trunc i32 %mul to i16
84  br label %for.inc
85
86for.inc:
87  %inc = add nsw i32 %i.0, 1
88  br label %for.cond
89
90for.end:
91  ret i16 %r.0
92}
93
94define signext i8 @or_v16i8(i8* %p) #0 {
95; CHECK-LABEL: @or_v16i8(
96; CHECK-NEXT:  entry:
97; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[P:%.*]] to <16 x i8>*
98; CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, <16 x i8>* [[TMP0]], align 1, !tbaa !6
99; CHECK-NEXT:    [[RDX_SHUF:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
100; CHECK-NEXT:    [[BIN_RDX:%.*]] = or <16 x i8> [[TMP1]], [[RDX_SHUF]]
101; CHECK-NEXT:    [[RDX_SHUF4:%.*]] = shufflevector <16 x i8> [[BIN_RDX]], <16 x i8> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
102; CHECK-NEXT:    [[BIN_RDX5:%.*]] = or <16 x i8> [[BIN_RDX]], [[RDX_SHUF4]]
103; CHECK-NEXT:    [[RDX_SHUF6:%.*]] = shufflevector <16 x i8> [[BIN_RDX5]], <16 x i8> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
104; CHECK-NEXT:    [[BIN_RDX7:%.*]] = or <16 x i8> [[BIN_RDX5]], [[RDX_SHUF6]]
105; CHECK-NEXT:    [[RDX_SHUF8:%.*]] = shufflevector <16 x i8> [[BIN_RDX7]], <16 x i8> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
106; CHECK-NEXT:    [[BIN_RDX9:%.*]] = or <16 x i8> [[BIN_RDX7]], [[RDX_SHUF8]]
107; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <16 x i8> [[BIN_RDX9]], i32 0
108; CHECK-NEXT:    ret i8 [[TMP2]]
109;
110entry:
111  br label %for.cond
112
113for.cond:
114  %r.0 = phi i8 [ 0, %entry ], [ %conv2, %for.inc ]
115  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
116  %cmp = icmp slt i32 %i.0, 16
117  br i1 %cmp, label %for.body, label %for.cond.cleanup
118
119for.cond.cleanup:
120  br label %for.end
121
122for.body:
123  %idxprom = sext i32 %i.0 to i64
124  %arrayidx = getelementptr inbounds i8, i8* %p, i64 %idxprom
125  %0 = load i8, i8* %arrayidx, align 1, !tbaa !9
126  %conv = sext i8 %0 to i32
127  %conv1 = sext i8 %r.0 to i32
128  %or = or i32 %conv1, %conv
129  %conv2 = trunc i32 %or to i8
130  br label %for.inc
131
132for.inc:
133  %inc = add nsw i32 %i.0, 1
134  br label %for.cond
135
136for.end:
137  ret i8 %r.0
138}
139
140define i32 @smin_v4i32(i32* %p) #0 {
141; CHECK-LABEL: @smin_v4i32(
142; CHECK-NEXT:  entry:
143; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>*
144; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4, !tbaa !0
145; CHECK-NEXT:    [[RDX_SHUF:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
146; CHECK-NEXT:    [[RDX_MINMAX_CMP:%.*]] = icmp slt <4 x i32> [[TMP1]], [[RDX_SHUF]]
147; CHECK-NEXT:    [[RDX_MINMAX_SELECT:%.*]] = select <4 x i1> [[RDX_MINMAX_CMP]], <4 x i32> [[TMP1]], <4 x i32> [[RDX_SHUF]]
148; CHECK-NEXT:    [[RDX_SHUF3:%.*]] = shufflevector <4 x i32> [[RDX_MINMAX_SELECT]], <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
149; CHECK-NEXT:    [[RDX_MINMAX_CMP4:%.*]] = icmp slt <4 x i32> [[RDX_MINMAX_SELECT]], [[RDX_SHUF3]]
150; CHECK-NEXT:    [[RDX_MINMAX_SELECT5:%.*]] = select <4 x i1> [[RDX_MINMAX_CMP4]], <4 x i32> [[RDX_MINMAX_SELECT]], <4 x i32> [[RDX_SHUF3]]
151; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i32> [[RDX_MINMAX_SELECT5]], i32 0
152; CHECK-NEXT:    ret i32 [[TMP2]]
153;
154entry:
155  br label %for.cond
156
157for.cond:
158  %r.0 = phi i32 [ 2147483647, %entry ], [ %cond, %for.inc ]
159  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
160  %cmp = icmp slt i32 %i.0, 4
161  br i1 %cmp, label %for.body, label %for.cond.cleanup
162
163for.cond.cleanup:
164  br label %for.end
165
166for.body:
167  %idxprom = sext i32 %i.0 to i64
168  %arrayidx = getelementptr inbounds i32, i32* %p, i64 %idxprom
169  %0 = load i32, i32* %arrayidx, align 4, !tbaa !3
170  %cmp1 = icmp slt i32 %0, %r.0
171  br i1 %cmp1, label %cond.true, label %cond.false
172
173cond.true:
174  %idxprom2 = sext i32 %i.0 to i64
175  %arrayidx3 = getelementptr inbounds i32, i32* %p, i64 %idxprom2
176  %1 = load i32, i32* %arrayidx3, align 4, !tbaa !3
177  br label %cond.end
178
179cond.false:
180  br label %cond.end
181
182cond.end:
183  %cond = phi i32 [ %1, %cond.true ], [ %r.0, %cond.false ]
184  br label %for.inc
185
186for.inc:
187  %inc = add nsw i32 %i.0, 1
188  br label %for.cond
189
190for.end:
191  ret i32 %r.0
192}
193
194define i32 @umax_v4i32(i32* %p) #0 {
195; CHECK-LABEL: @umax_v4i32(
196; CHECK-NEXT:  entry:
197; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>*
198; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4, !tbaa !0
199; CHECK-NEXT:    [[RDX_SHUF:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
200; CHECK-NEXT:    [[RDX_MINMAX_CMP:%.*]] = icmp ugt <4 x i32> [[TMP1]], [[RDX_SHUF]]
201; CHECK-NEXT:    [[RDX_MINMAX_SELECT:%.*]] = select <4 x i1> [[RDX_MINMAX_CMP]], <4 x i32> [[TMP1]], <4 x i32> [[RDX_SHUF]]
202; CHECK-NEXT:    [[RDX_SHUF3:%.*]] = shufflevector <4 x i32> [[RDX_MINMAX_SELECT]], <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
203; CHECK-NEXT:    [[RDX_MINMAX_CMP4:%.*]] = icmp ugt <4 x i32> [[RDX_MINMAX_SELECT]], [[RDX_SHUF3]]
204; CHECK-NEXT:    [[RDX_MINMAX_SELECT5:%.*]] = select <4 x i1> [[RDX_MINMAX_CMP4]], <4 x i32> [[RDX_MINMAX_SELECT]], <4 x i32> [[RDX_SHUF3]]
205; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i32> [[RDX_MINMAX_SELECT5]], i32 0
206; CHECK-NEXT:    ret i32 [[TMP2]]
207;
208entry:
209  br label %for.cond
210
211for.cond:
212  %r.0 = phi i32 [ 0, %entry ], [ %cond, %for.inc ]
213  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
214  %cmp = icmp slt i32 %i.0, 4
215  br i1 %cmp, label %for.body, label %for.cond.cleanup
216
217for.cond.cleanup:
218  br label %for.end
219
220for.body:
221  %idxprom = sext i32 %i.0 to i64
222  %arrayidx = getelementptr inbounds i32, i32* %p, i64 %idxprom
223  %0 = load i32, i32* %arrayidx, align 4, !tbaa !3
224  %cmp1 = icmp ugt i32 %0, %r.0
225  br i1 %cmp1, label %cond.true, label %cond.false
226
227cond.true:
228  %idxprom2 = sext i32 %i.0 to i64
229  %arrayidx3 = getelementptr inbounds i32, i32* %p, i64 %idxprom2
230  %1 = load i32, i32* %arrayidx3, align 4, !tbaa !3
231  br label %cond.end
232
233cond.false:
234  br label %cond.end
235
236cond.end:
237  %cond = phi i32 [ %1, %cond.true ], [ %r.0, %cond.false ]
238  br label %for.inc
239
240for.inc:
241  %inc = add nsw i32 %i.0, 1
242  br label %for.cond
243
244for.end:
245  ret i32 %r.0
246}
247
248define float @fadd_v4i32(float* %p) #0 {
249; CHECK-LABEL: @fadd_v4i32(
250; CHECK-NEXT:  entry:
251; CHECK-NEXT:    [[TMP0:%.*]] = bitcast float* [[P:%.*]] to <4 x float>*
252; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x float>, <4 x float>* [[TMP0]], align 4, !tbaa !7
253; CHECK-NEXT:    [[RDX_SHUF:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
254; CHECK-NEXT:    [[BIN_RDX:%.*]] = fadd fast <4 x float> [[TMP1]], [[RDX_SHUF]]
255; CHECK-NEXT:    [[RDX_SHUF3:%.*]] = shufflevector <4 x float> [[BIN_RDX]], <4 x float> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
256; CHECK-NEXT:    [[BIN_RDX4:%.*]] = fadd fast <4 x float> [[BIN_RDX]], [[RDX_SHUF3]]
257; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x float> [[BIN_RDX4]], i32 0
258; CHECK-NEXT:    [[BIN_RDX5:%.*]] = fadd fast float 0.000000e+00, [[TMP2]]
259; CHECK-NEXT:    [[OP_EXTRA:%.*]] = fadd fast float [[BIN_RDX5]], 4.200000e+01
260; CHECK-NEXT:    ret float [[OP_EXTRA]]
261;
262entry:
263  br label %for.cond
264
265for.cond:
266  %r.0 = phi float [ 4.200000e+01, %entry ], [ %add, %for.inc ]
267  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
268  %cmp = icmp slt i32 %i.0, 4
269  br i1 %cmp, label %for.body, label %for.cond.cleanup
270
271for.cond.cleanup:
272  br label %for.end
273
274for.body:
275  %idxprom = sext i32 %i.0 to i64
276  %arrayidx = getelementptr inbounds float, float* %p, i64 %idxprom
277  %0 = load float, float* %arrayidx, align 4, !tbaa !10
278  %add = fadd fast float %r.0, %0
279  br label %for.inc
280
281for.inc:
282  %inc = add nsw i32 %i.0, 1
283  br label %for.cond
284
285for.end:
286  ret float %r.0
287}
288
289define float @fmul_v4i32(float* %p) #0 {
290; CHECK-LABEL: @fmul_v4i32(
291; CHECK-NEXT:  entry:
292; CHECK-NEXT:    [[TMP0:%.*]] = bitcast float* [[P:%.*]] to <4 x float>*
293; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x float>, <4 x float>* [[TMP0]], align 4, !tbaa !7
294; CHECK-NEXT:    [[RDX_SHUF:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
295; CHECK-NEXT:    [[BIN_RDX:%.*]] = fmul fast <4 x float> [[TMP1]], [[RDX_SHUF]]
296; CHECK-NEXT:    [[RDX_SHUF3:%.*]] = shufflevector <4 x float> [[BIN_RDX]], <4 x float> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
297; CHECK-NEXT:    [[BIN_RDX4:%.*]] = fmul fast <4 x float> [[BIN_RDX]], [[RDX_SHUF3]]
298; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x float> [[BIN_RDX4]], i32 0
299; CHECK-NEXT:    [[BIN_RDX5:%.*]] = fmul fast float 1.000000e+00, [[TMP2]]
300; CHECK-NEXT:    [[OP_EXTRA:%.*]] = fmul fast float [[BIN_RDX5]], 4.200000e+01
301; CHECK-NEXT:    ret float [[OP_EXTRA]]
302;
303entry:
304  br label %for.cond
305
306for.cond:
307  %r.0 = phi float [ 4.200000e+01, %entry ], [ %mul, %for.inc ]
308  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
309  %cmp = icmp slt i32 %i.0, 4
310  br i1 %cmp, label %for.body, label %for.cond.cleanup
311
312for.cond.cleanup:
313  br label %for.end
314
315for.body:
316  %idxprom = sext i32 %i.0 to i64
317  %arrayidx = getelementptr inbounds float, float* %p, i64 %idxprom
318  %0 = load float, float* %arrayidx, align 4, !tbaa !10
319  %mul = fmul fast float %r.0, %0
320  br label %for.inc
321
322for.inc:
323  %inc = add nsw i32 %i.0, 1
324  br label %for.cond
325
326for.end:
327  ret float %r.0
328}
329
330define float @fmin_v4i32(float* %p) #0 {
331; CHECK-LABEL: @fmin_v4i32(
332; CHECK-NEXT:  entry:
333; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[P:%.*]], align 4, !tbaa !7
334; CHECK-NEXT:    [[TMP1:%.*]] = tail call fast float @llvm.minnum.f32(float [[TMP0]], float 0x47EFFFFFE0000000)
335; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds float, float* [[P]], i64 1
336; CHECK-NEXT:    [[TMP2:%.*]] = load float, float* [[ARRAYIDX_1]], align 4, !tbaa !7
337; CHECK-NEXT:    [[TMP3:%.*]] = tail call fast float @llvm.minnum.f32(float [[TMP2]], float [[TMP1]])
338; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds float, float* [[P]], i64 2
339; CHECK-NEXT:    [[TMP4:%.*]] = load float, float* [[ARRAYIDX_2]], align 4, !tbaa !7
340; CHECK-NEXT:    [[TMP5:%.*]] = tail call fast float @llvm.minnum.f32(float [[TMP4]], float [[TMP3]])
341; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds float, float* [[P]], i64 3
342; CHECK-NEXT:    [[TMP6:%.*]] = load float, float* [[ARRAYIDX_3]], align 4, !tbaa !7
343; CHECK-NEXT:    [[TMP7:%.*]] = tail call fast float @llvm.minnum.f32(float [[TMP6]], float [[TMP5]])
344; CHECK-NEXT:    ret float [[TMP7]]
345;
346entry:
347  br label %for.cond
348
349for.cond:
350  %r.0 = phi float [  0x47EFFFFFE0000000, %entry ], [ %cond, %for.inc ]
351  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
352  %cmp = icmp slt i32 %i.0, 4
353  br i1 %cmp, label %for.body, label %for.cond.cleanup
354
355for.cond.cleanup:
356  br label %for.end
357
358for.body:
359  %idxprom = sext i32 %i.0 to i64
360  %arrayidx = getelementptr inbounds float, float* %p, i64 %idxprom
361  %0 = load float, float* %arrayidx, align 4, !tbaa !10
362  %cmp1 = fcmp fast olt float %0, %r.0
363  br i1 %cmp1, label %cond.true, label %cond.false
364
365cond.true:
366  %idxprom2 = sext i32 %i.0 to i64
367  %arrayidx3 = getelementptr inbounds float, float* %p, i64 %idxprom2
368  %1 = load float, float* %arrayidx3, align 4, !tbaa !10
369  br label %cond.end
370
371cond.false:
372  br label %cond.end
373
374cond.end:
375  %cond = phi fast float [ %1, %cond.true ], [ %r.0, %cond.false ]
376  br label %for.inc
377
378for.inc:
379  %inc = add nsw i32 %i.0, 1
380  br label %for.cond
381
382for.end:
383  ret float %r.0
384}
385
386attributes #0 = { nounwind ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+avx,+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" "unsafe-fp-math"="true" "use-soft-float"="false" }
387;attributes #1 = { argmemonly nounwind willreturn }
388
389!0 = !{i32 1, !"wchar_size", i32 4}
390!1 = !{i32 7, !"PIC Level", i32 2}
391!2 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git a9fe69c359de653015c39e413e48630d069abe27)"}
392!3 = !{!4, !4, i64 0}
393!4 = !{!"int", !5, i64 0}
394!5 = !{!"omnipotent char", !6, i64 0}
395!6 = !{!"Simple C/C++ TBAA"}
396!7 = !{!8, !8, i64 0}
397!8 = !{!"short", !5, i64 0}
398!9 = !{!5, !5, i64 0}
399!10 = !{!11, !11, i64 0}
400!11 = !{!"float", !5, i64 0}
401