1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S | FileCheck %s
3; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4
5declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
6declare {i8, i1} @llvm.sadd.with.overflow.i8(i8 %a, i8 %b)
7declare {i8, i1} @llvm.usub.with.overflow.i8(i8 %a, i8 %b)
8declare {i8, i1} @llvm.ssub.with.overflow.i8(i8 %a, i8 %b)
9declare {i8, i1} @llvm.umul.with.overflow.i8(i8 %a, i8 %b)
10declare {i8, i1} @llvm.smul.with.overflow.i8(i8 %a, i8 %b)
11
12define i1 @test_uadd1() {
13; CHECK-LABEL: @test_uadd1(
14; CHECK-NEXT:    ret i1 true
15;
16  %x = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 254, i8 3)
17  %overflow = extractvalue {i8, i1} %x, 1
18  ret i1 %overflow
19}
20
21define i8 @test_uadd2() {
22; CHECK-LABEL: @test_uadd2(
23; CHECK-NEXT:    ret i8 42
24;
25  %x = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 254, i8 44)
26  %result = extractvalue {i8, i1} %x, 0
27  ret i8 %result
28}
29
30define {i8, i1} @test_uadd3(i8 %v) {
31; CHECK-LABEL: @test_uadd3(
32; CHECK-NEXT:    ret { i8, i1 } { i8 -1, i1 false }
33;
34  %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v, i8 undef)
35  ret {i8, i1} %result
36}
37
38define {i8, i1} @test_uadd3_poison(i8 %v) {
39; CHECK-LABEL: @test_uadd3_poison(
40; CHECK-NEXT:    ret { i8, i1 } { i8 -1, i1 false }
41;
42  %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v, i8 poison)
43  ret {i8, i1} %result
44}
45
46define {i8, i1} @test_uadd4(i8 %v) {
47; CHECK-LABEL: @test_uadd4(
48; CHECK-NEXT:    ret { i8, i1 } { i8 -1, i1 false }
49;
50  %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 undef, i8 %v)
51  ret {i8, i1} %result
52}
53
54define {i8, i1} @test_uadd4_poison(i8 %v) {
55; CHECK-LABEL: @test_uadd4_poison(
56; CHECK-NEXT:    ret { i8, i1 } { i8 -1, i1 false }
57;
58  %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 poison, i8 %v)
59  ret {i8, i1} %result
60}
61
62define i1 @test_sadd1() {
63; CHECK-LABEL: @test_sadd1(
64; CHECK-NEXT:    ret i1 true
65;
66  %x = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 126, i8 3)
67  %overflow = extractvalue {i8, i1} %x, 1
68  ret i1 %overflow
69}
70
71define i8 @test_sadd2() {
72; CHECK-LABEL: @test_sadd2(
73; CHECK-NEXT:    ret i8 -86
74;
75  %x = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 126, i8 44)
76  %result = extractvalue {i8, i1} %x, 0
77  ret i8 %result
78}
79
80define {i8, i1} @test_sadd3(i8 %v) {
81; CHECK-LABEL: @test_sadd3(
82; CHECK-NEXT:    ret { i8, i1 } { i8 -1, i1 false }
83;
84  %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v, i8 undef)
85  ret {i8, i1} %result
86}
87
88define {i8, i1} @test_sadd3_poison(i8 %v) {
89; CHECK-LABEL: @test_sadd3_poison(
90; CHECK-NEXT:    ret { i8, i1 } { i8 -1, i1 false }
91;
92  %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v, i8 poison)
93  ret {i8, i1} %result
94}
95
96define {i8, i1} @test_sadd4(i8 %v) {
97; CHECK-LABEL: @test_sadd4(
98; CHECK-NEXT:    ret { i8, i1 } { i8 -1, i1 false }
99;
100  %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 undef, i8 %v)
101  ret {i8, i1} %result
102}
103
104define {i8, i1} @test_sadd4_poison(i8 %v) {
105; CHECK-LABEL: @test_sadd4_poison(
106; CHECK-NEXT:    ret { i8, i1 } { i8 -1, i1 false }
107;
108  %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 poison, i8 %v)
109  ret {i8, i1} %result
110}
111
112define {i8, i1} @test_usub1(i8 %V) {
113; CHECK-LABEL: @test_usub1(
114; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
115;
116  %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 %V)
117  ret {i8, i1} %x
118}
119
120define {i8, i1} @test_usub2(i8 %V) {
121; CHECK-LABEL: @test_usub2(
122; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
123;
124  %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 undef)
125  ret {i8, i1} %x
126}
127
128define {i8, i1} @test_usub2_poison(i8 %V) {
129; CHECK-LABEL: @test_usub2_poison(
130; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
131;
132  %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 poison)
133  ret {i8, i1} %x
134}
135
136define {i8, i1} @test_usub3(i8 %V) {
137; CHECK-LABEL: @test_usub3(
138; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
139;
140  %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 undef, i8 %V)
141  ret {i8, i1} %x
142}
143
144define {i8, i1} @test_usub3_poison(i8 %V) {
145; CHECK-LABEL: @test_usub3_poison(
146; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
147;
148  %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 poison, i8 %V)
149  ret {i8, i1} %x
150}
151
152define {i8, i1} @test_ssub1(i8 %V) {
153; CHECK-LABEL: @test_ssub1(
154; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
155;
156  %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 %V)
157  ret {i8, i1} %x
158}
159
160define {i8, i1} @test_ssub2(i8 %V) {
161; CHECK-LABEL: @test_ssub2(
162; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
163;
164  %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 undef)
165  ret {i8, i1} %x
166}
167
168define {i8, i1} @test_ssub2_poison(i8 %V) {
169; CHECK-LABEL: @test_ssub2_poison(
170; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
171;
172  %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 poison)
173  ret {i8, i1} %x
174}
175
176define {i8, i1} @test_ssub3(i8 %V) {
177; CHECK-LABEL: @test_ssub3(
178; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
179;
180  %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 undef, i8 %V)
181  ret {i8, i1} %x
182}
183
184define {i8, i1} @test_ssub3_poison(i8 %V) {
185; CHECK-LABEL: @test_ssub3_poison(
186; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
187;
188  %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 poison, i8 %V)
189  ret {i8, i1} %x
190}
191
192define {i8, i1} @test_umul1(i8 %V) {
193; CHECK-LABEL: @test_umul1(
194; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
195;
196  %x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %V, i8 0)
197  ret {i8, i1} %x
198}
199
200define {i8, i1} @test_umul2(i8 %V) {
201; CHECK-LABEL: @test_umul2(
202; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
203;
204  %x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %V, i8 undef)
205  ret {i8, i1} %x
206}
207
208define {i8, i1} @test_umul2_poison(i8 %V) {
209; CHECK-LABEL: @test_umul2_poison(
210; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
211;
212  %x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %V, i8 poison)
213  ret {i8, i1} %x
214}
215
216define {i8, i1} @test_umul3(i8 %V) {
217; CHECK-LABEL: @test_umul3(
218; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
219;
220  %x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 0, i8 %V)
221  ret {i8, i1} %x
222}
223
224define {i8, i1} @test_umul4(i8 %V) {
225; CHECK-LABEL: @test_umul4(
226; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
227;
228  %x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 undef, i8 %V)
229  ret {i8, i1} %x
230}
231
232define {i8, i1} @test_umul4_poison(i8 %V) {
233; CHECK-LABEL: @test_umul4_poison(
234; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
235;
236  %x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 poison, i8 %V)
237  ret {i8, i1} %x
238}
239
240define {i8, i1} @test_smul1(i8 %V) {
241; CHECK-LABEL: @test_smul1(
242; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
243;
244  %x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %V, i8 0)
245  ret {i8, i1} %x
246}
247
248define {i8, i1} @test_smul2(i8 %V) {
249; CHECK-LABEL: @test_smul2(
250; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
251;
252  %x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %V, i8 undef)
253  ret {i8, i1} %x
254}
255
256define {i8, i1} @test_smul2_poison(i8 %V) {
257; CHECK-LABEL: @test_smul2_poison(
258; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
259;
260  %x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %V, i8 poison)
261  ret {i8, i1} %x
262}
263
264define {i8, i1} @test_smul3(i8 %V) {
265; CHECK-LABEL: @test_smul3(
266; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
267;
268  %x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 0, i8 %V)
269  ret {i8, i1} %x
270}
271
272define {i8, i1} @test_smul4(i8 %V) {
273; CHECK-LABEL: @test_smul4(
274; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
275;
276  %x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 undef, i8 %V)
277  ret {i8, i1} %x
278}
279
280define {i8, i1} @test_smul4_poison(i8 %V) {
281; CHECK-LABEL: @test_smul4_poison(
282; CHECK-NEXT:    ret { i8, i1 } zeroinitializer
283;
284  %x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 poison, i8 %V)
285  ret {i8, i1} %x
286}
287
288; Test a non-intrinsic that we know about as a library call.
289declare float @fabs(float %x)
290
291define float @test_fabs_libcall() {
292; CHECK-LABEL: @test_fabs_libcall(
293; CHECK-NEXT:    [[X:%.*]] = call float @fabs(float -4.200000e+01)
294; CHECK-NEXT:    ret float 4.200000e+01
295;
296
297  %x = call float @fabs(float -42.0)
298; This is still a real function call, so instsimplify won't nuke it -- other
299; passes have to do that.
300
301  ret float %x
302}
303
304
305declare float @llvm.fabs.f32(float) nounwind readnone
306declare float @llvm.floor.f32(float) nounwind readnone
307declare float @llvm.ceil.f32(float) nounwind readnone
308declare float @llvm.trunc.f32(float) nounwind readnone
309declare float @llvm.rint.f32(float) nounwind readnone
310declare float @llvm.nearbyint.f32(float) nounwind readnone
311declare float @llvm.canonicalize.f32(float) nounwind readnone
312
313; Test idempotent intrinsics
314define float @test_idempotence(float %a) {
315; CHECK-LABEL: @test_idempotence(
316; CHECK-NEXT:    [[A0:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
317; CHECK-NEXT:    [[B0:%.*]] = call float @llvm.floor.f32(float [[A]])
318; CHECK-NEXT:    [[C0:%.*]] = call float @llvm.ceil.f32(float [[A]])
319; CHECK-NEXT:    [[D0:%.*]] = call float @llvm.trunc.f32(float [[A]])
320; CHECK-NEXT:    [[E0:%.*]] = call float @llvm.rint.f32(float [[A]])
321; CHECK-NEXT:    [[F0:%.*]] = call float @llvm.nearbyint.f32(float [[A]])
322; CHECK-NEXT:    [[G0:%.*]] = call float @llvm.canonicalize.f32(float [[A]])
323; CHECK-NEXT:    [[R0:%.*]] = fadd float [[A0]], [[B0]]
324; CHECK-NEXT:    [[R1:%.*]] = fadd float [[R0]], [[C0]]
325; CHECK-NEXT:    [[R2:%.*]] = fadd float [[R1]], [[D0]]
326; CHECK-NEXT:    [[R3:%.*]] = fadd float [[R2]], [[E0]]
327; CHECK-NEXT:    [[R4:%.*]] = fadd float [[R3]], [[F0]]
328; CHECK-NEXT:    [[R5:%.*]] = fadd float [[R4]], [[G0]]
329; CHECK-NEXT:    ret float [[R5]]
330;
331
332  %a0 = call float @llvm.fabs.f32(float %a)
333  %a1 = call float @llvm.fabs.f32(float %a0)
334
335  %b0 = call float @llvm.floor.f32(float %a)
336  %b1 = call float @llvm.floor.f32(float %b0)
337
338  %c0 = call float @llvm.ceil.f32(float %a)
339  %c1 = call float @llvm.ceil.f32(float %c0)
340
341  %d0 = call float @llvm.trunc.f32(float %a)
342  %d1 = call float @llvm.trunc.f32(float %d0)
343
344  %e0 = call float @llvm.rint.f32(float %a)
345  %e1 = call float @llvm.rint.f32(float %e0)
346
347  %f0 = call float @llvm.nearbyint.f32(float %a)
348  %f1 = call float @llvm.nearbyint.f32(float %f0)
349
350  %g0 = call float @llvm.canonicalize.f32(float %a)
351  %g1 = call float @llvm.canonicalize.f32(float %g0)
352
353  %r0 = fadd float %a1, %b1
354  %r1 = fadd float %r0, %c1
355  %r2 = fadd float %r1, %d1
356  %r3 = fadd float %r2, %e1
357  %r4 = fadd float %r3, %f1
358  %r5 = fadd float %r4, %g1
359
360  ret float %r5
361}
362
363define i8* @operator_new() {
364; CHECK-LABEL: @operator_new(
365; CHECK-NEXT:  entry:
366; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @_Znwm(i64 8)
367; CHECK-NEXT:    br i1 false, label [[CAST_END:%.*]], label [[CAST_NOTNULL:%.*]]
368; CHECK:       cast.notnull:
369; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 4
370; CHECK-NEXT:    br label [[CAST_END]]
371; CHECK:       cast.end:
372; CHECK-NEXT:    [[CAST_RESULT:%.*]] = phi i8* [ [[ADD_PTR]], [[CAST_NOTNULL]] ], [ null, [[ENTRY:%.*]] ]
373; CHECK-NEXT:    ret i8* [[CAST_RESULT]]
374;
375entry:
376  %call = tail call noalias i8* @_Znwm(i64 8)
377  %cmp = icmp eq i8* %call, null
378  br i1 %cmp, label %cast.end, label %cast.notnull
379
380cast.notnull:                                     ; preds = %entry
381  %add.ptr = getelementptr inbounds i8, i8* %call, i64 4
382  br label %cast.end
383
384cast.end:                                         ; preds = %cast.notnull, %entry
385  %cast.result = phi i8* [ %add.ptr, %cast.notnull ], [ null, %entry ]
386  ret i8* %cast.result
387
388}
389
390declare nonnull noalias i8* @_Znwm(i64)
391
392%"struct.std::nothrow_t" = type { i8 }
393@_ZSt7nothrow = external global %"struct.std::nothrow_t"
394
395define i8* @operator_new_nothrow_t() {
396; CHECK-LABEL: @operator_new_nothrow_t(
397; CHECK-NEXT:  entry:
398; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @_ZnamRKSt9nothrow_t(i64 8, %"struct.std::nothrow_t"* @_ZSt7nothrow)
399; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8* [[CALL]], null
400; CHECK-NEXT:    br i1 [[CMP]], label [[CAST_END:%.*]], label [[CAST_NOTNULL:%.*]]
401; CHECK:       cast.notnull:
402; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 4
403; CHECK-NEXT:    br label [[CAST_END]]
404; CHECK:       cast.end:
405; CHECK-NEXT:    [[CAST_RESULT:%.*]] = phi i8* [ [[ADD_PTR]], [[CAST_NOTNULL]] ], [ null, [[ENTRY:%.*]] ]
406; CHECK-NEXT:    ret i8* [[CAST_RESULT]]
407;
408entry:
409  %call = tail call noalias i8* @_ZnamRKSt9nothrow_t(i64 8, %"struct.std::nothrow_t"* @_ZSt7nothrow)
410  %cmp = icmp eq i8* %call, null
411  br i1 %cmp, label %cast.end, label %cast.notnull
412
413cast.notnull:                                     ; preds = %entry
414  %add.ptr = getelementptr inbounds i8, i8* %call, i64 4
415  br label %cast.end
416
417cast.end:                                         ; preds = %cast.notnull, %entry
418  %cast.result = phi i8* [ %add.ptr, %cast.notnull ], [ null, %entry ]
419  ret i8* %cast.result
420
421}
422
423declare i8* @_ZnamRKSt9nothrow_t(i64, %"struct.std::nothrow_t"*) nounwind
424
425define i8* @malloc_can_return_null() {
426; CHECK-LABEL: @malloc_can_return_null(
427; CHECK-NEXT:  entry:
428; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @malloc(i64 8)
429; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8* [[CALL]], null
430; CHECK-NEXT:    br i1 [[CMP]], label [[CAST_END:%.*]], label [[CAST_NOTNULL:%.*]]
431; CHECK:       cast.notnull:
432; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 4
433; CHECK-NEXT:    br label [[CAST_END]]
434; CHECK:       cast.end:
435; CHECK-NEXT:    [[CAST_RESULT:%.*]] = phi i8* [ [[ADD_PTR]], [[CAST_NOTNULL]] ], [ null, [[ENTRY:%.*]] ]
436; CHECK-NEXT:    ret i8* [[CAST_RESULT]]
437;
438entry:
439  %call = tail call noalias i8* @malloc(i64 8)
440  %cmp = icmp eq i8* %call, null
441  br i1 %cmp, label %cast.end, label %cast.notnull
442
443cast.notnull:                                     ; preds = %entry
444  %add.ptr = getelementptr inbounds i8, i8* %call, i64 4
445  br label %cast.end
446
447cast.end:                                         ; preds = %cast.notnull, %entry
448  %cast.result = phi i8* [ %add.ptr, %cast.notnull ], [ null, %entry ]
449  ret i8* %cast.result
450
451}
452
453define i32 @call_null() {
454; CHECK-LABEL: @call_null(
455; CHECK-NEXT:  entry:
456; CHECK-NEXT:    [[CALL:%.*]] = call i32 null()
457; CHECK-NEXT:    ret i32 poison
458;
459entry:
460  %call = call i32 null()
461  ret i32 %call
462}
463
464define i32 @call_undef() {
465; CHECK-LABEL: @call_undef(
466; CHECK-NEXT:  entry:
467; CHECK-NEXT:    [[CALL:%.*]] = call i32 undef()
468; CHECK-NEXT:    ret i32 poison
469;
470entry:
471  %call = call i32 undef()
472  ret i32 %call
473}
474
475@GV = private constant [8 x i32] [i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48, i32 49]
476
477define <8 x i32> @partial_masked_load() {
478; CHECK-LABEL: @partial_masked_load(
479; CHECK-NEXT:    ret <8 x i32> <i32 undef, i32 undef, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47>
480;
481  %masked.load = call <8 x i32> @llvm.masked.load.v8i32.p0v8i32(<8 x i32>* bitcast (i32* getelementptr ([8 x i32], [8 x i32]* @GV, i64 0, i64 -2) to <8 x i32>*), i32 4, <8 x i1> <i1 false, i1 false, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef)
482  ret <8 x i32> %masked.load
483}
484
485define <8 x i32> @masked_load_undef_mask(<8 x i32>* %V) {
486; CHECK-LABEL: @masked_load_undef_mask(
487; CHECK-NEXT:    ret <8 x i32> <i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0>
488;
489  %masked.load = call <8 x i32> @llvm.masked.load.v8i32.p0v8i32(<8 x i32>* %V, i32 4, <8 x i1> undef, <8 x i32> <i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0>)
490  ret <8 x i32> %masked.load
491}
492
493declare noalias i8* @malloc(i64)
494
495declare <8 x i32> @llvm.masked.load.v8i32.p0v8i32(<8 x i32>*, i32, <8 x i1>, <8 x i32>)
496
497declare double @llvm.powi.f64.i16(double, i16)
498declare <2 x double> @llvm.powi.v2f64.i16(<2 x double>, i16)
499declare double @llvm.powi.f64.i32(double, i32)
500declare <2 x double> @llvm.powi.v2f64.i32(<2 x double>, i32)
501
502define double @constant_fold_powi() {
503; CHECK-LABEL: @constant_fold_powi(
504; CHECK-NEXT:    ret double 9.000000e+00
505;
506  %t0 = call double @llvm.powi.f64.i32(double 3.00000e+00, i32 2)
507  ret double %t0
508}
509
510define double @constant_fold_powi_i16() {
511; CHECK-LABEL: @constant_fold_powi_i16(
512; CHECK-NEXT:    ret double 9.000000e+00
513;
514  %t0 = call double @llvm.powi.f64.i16(double 3.00000e+00, i16 2)
515  ret double %t0
516}
517
518define <2 x double> @constant_fold_powi_vec() {
519; CHECK-LABEL: @constant_fold_powi_vec(
520; CHECK-NEXT:    ret <2 x double> <double 9.000000e+00, double 2.500000e+01>
521;
522  %t0 = call <2 x double> @llvm.powi.v2f64.i32(<2 x double> <double 3.00000e+00, double 5.00000e+00>, i32 2)
523  ret <2 x double> %t0
524}
525
526define <2 x double> @constant_fold_powi_vec_i16() {
527; CHECK-LABEL: @constant_fold_powi_vec_i16(
528; CHECK-NEXT:    ret <2 x double> <double 9.000000e+00, double 2.500000e+01>
529;
530  %t0 = call <2 x double> @llvm.powi.v2f64.i16(<2 x double> <double 3.00000e+00, double 5.00000e+00>, i16 2)
531  ret <2 x double> %t0
532}
533
534declare i8 @llvm.fshl.i8(i8, i8, i8)
535declare i9 @llvm.fshr.i9(i9, i9, i9)
536declare <2 x i7> @llvm.fshl.v2i7(<2 x i7>, <2 x i7>, <2 x i7>)
537declare <2 x i8> @llvm.fshr.v2i8(<2 x i8>, <2 x i8>, <2 x i8>)
538
539define i8 @fshl_no_shift(i8 %x, i8 %y) {
540; CHECK-LABEL: @fshl_no_shift(
541; CHECK-NEXT:    ret i8 [[X:%.*]]
542;
543  %z = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 0)
544  ret i8 %z
545}
546
547define i9 @fshr_no_shift(i9 %x, i9 %y) {
548; CHECK-LABEL: @fshr_no_shift(
549; CHECK-NEXT:    ret i9 [[Y:%.*]]
550;
551  %z = call i9 @llvm.fshr.i9(i9 %x, i9 %y, i9 0)
552  ret i9 %z
553}
554
555define i8 @fshl_no_shift_modulo_bitwidth(i8 %x, i8 %y) {
556; CHECK-LABEL: @fshl_no_shift_modulo_bitwidth(
557; CHECK-NEXT:    ret i8 [[X:%.*]]
558;
559  %z = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 40)
560  ret i8 %z
561}
562
563define i9 @fshr_no_shift_modulo_bitwidth(i9 %x, i9 %y) {
564; CHECK-LABEL: @fshr_no_shift_modulo_bitwidth(
565; CHECK-NEXT:    ret i9 [[Y:%.*]]
566;
567  %z = call i9 @llvm.fshr.i9(i9 %x, i9 %y, i9 189)
568  ret i9 %z
569}
570
571define <2 x i7> @fshl_no_shift_modulo_bitwidth_splat(<2 x i7> %x, <2 x i7> %y) {
572; CHECK-LABEL: @fshl_no_shift_modulo_bitwidth_splat(
573; CHECK-NEXT:    ret <2 x i7> [[X:%.*]]
574;
575  %z = call <2 x i7> @llvm.fshl.v2i7(<2 x i7> %x, <2 x i7> %y, <2 x i7> <i7 21, i7 21>)
576  ret <2 x i7> %z
577}
578
579define <2 x i8> @fshr_no_shift_modulo_bitwidth_splat(<2 x i8> %x, <2 x i8> %y) {
580; CHECK-LABEL: @fshr_no_shift_modulo_bitwidth_splat(
581; CHECK-NEXT:    ret <2 x i8> [[Y:%.*]]
582;
583  %z = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> %x, <2 x i8> %y, <2 x i8> <i8 72, i8 72>)
584  ret <2 x i8> %z
585}
586
587; If y is poison, eliminating the guard is not safe.
588
589define i8 @fshl_zero_shift_guard(i8 %x, i8 %y, i8 %sh) {
590; CHECK-LABEL: @fshl_zero_shift_guard(
591; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[SH:%.*]], 0
592; CHECK-NEXT:    [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[SH]])
593; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i8 [[X]], i8 [[F]]
594; CHECK-NEXT:    ret i8 [[S]]
595;
596  %c = icmp eq i8 %sh, 0
597  %f = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %sh)
598  %s = select i1 %c, i8 %x, i8 %f
599  ret i8 %s
600}
601
602; If y is poison, eliminating the guard is not safe.
603
604define i8 @fshl_zero_shift_guard_swapped(i8 %x, i8 %y, i8 %sh) {
605; CHECK-LABEL: @fshl_zero_shift_guard_swapped(
606; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[SH:%.*]], 0
607; CHECK-NEXT:    [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[SH]])
608; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i8 [[F]], i8 [[X]]
609; CHECK-NEXT:    ret i8 [[S]]
610;
611  %c = icmp ne i8 %sh, 0
612  %f = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %sh)
613  %s = select i1 %c, i8 %f, i8 %x
614  ret i8 %s
615}
616
617; When the shift amount is 0, fshl returns its 1st parameter (x), so everything is deleted.
618
619define i8 @fshl_zero_shift_guard_inverted(i8 %x, i8 %y, i8 %sh) {
620; CHECK-LABEL: @fshl_zero_shift_guard_inverted(
621; CHECK-NEXT:    ret i8 [[X:%.*]]
622;
623  %c = icmp eq i8 %sh, 0
624  %f = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %sh)
625  %s = select i1 %c, i8 %f, i8 %x
626  ret i8 %s
627}
628
629; When the shift amount is 0, fshl returns its 1st parameter (x), so everything is deleted.
630
631define i8 @fshl_zero_shift_guard_inverted_swapped(i8 %x, i8 %y, i8 %sh) {
632; CHECK-LABEL: @fshl_zero_shift_guard_inverted_swapped(
633; CHECK-NEXT:    ret i8 [[X:%.*]]
634;
635  %c = icmp ne i8 %sh, 0
636  %f = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %sh)
637  %s = select i1 %c, i8 %x, i8 %f
638  ret i8 %s
639}
640
641; If x is poison, eliminating the guard is not safe.
642
643define i9 @fshr_zero_shift_guard(i9 %x, i9 %y, i9 %sh) {
644; CHECK-LABEL: @fshr_zero_shift_guard(
645; CHECK-NEXT:    [[C:%.*]] = icmp eq i9 [[SH:%.*]], 0
646; CHECK-NEXT:    [[F:%.*]] = call i9 @llvm.fshr.i9(i9 [[X:%.*]], i9 [[Y:%.*]], i9 [[SH]])
647; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i9 [[Y]], i9 [[F]]
648; CHECK-NEXT:    ret i9 [[S]]
649;
650  %c = icmp eq i9 %sh, 0
651  %f = call i9 @llvm.fshr.i9(i9 %x, i9 %y, i9 %sh)
652  %s = select i1 %c, i9 %y, i9 %f
653  ret i9 %s
654}
655
656; If x is poison, eliminating the guard is not safe.
657
658define i9 @fshr_zero_shift_guard_swapped(i9 %x, i9 %y, i9 %sh) {
659; CHECK-LABEL: @fshr_zero_shift_guard_swapped(
660; CHECK-NEXT:    [[C:%.*]] = icmp ne i9 [[SH:%.*]], 0
661; CHECK-NEXT:    [[F:%.*]] = call i9 @llvm.fshr.i9(i9 [[X:%.*]], i9 [[Y:%.*]], i9 [[SH]])
662; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i9 [[F]], i9 [[Y]]
663; CHECK-NEXT:    ret i9 [[S]]
664;
665  %c = icmp ne i9 %sh, 0
666  %f = call i9 @llvm.fshr.i9(i9 %x, i9 %y, i9 %sh)
667  %s = select i1 %c, i9 %f, i9 %y
668  ret i9 %s
669}
670
671; When the shift amount is 0, fshr returns its 2nd parameter (y), so everything is deleted.
672
673define i9 @fshr_zero_shift_guard_inverted(i9 %x, i9 %y, i9 %sh) {
674; CHECK-LABEL: @fshr_zero_shift_guard_inverted(
675; CHECK-NEXT:    ret i9 [[Y:%.*]]
676;
677  %c = icmp eq i9 %sh, 0
678  %f = call i9 @llvm.fshr.i9(i9 %x, i9 %y, i9 %sh)
679  %s = select i1 %c, i9 %f, i9 %y
680  ret i9 %s
681}
682
683; When the shift amount is 0, fshr returns its 2nd parameter (y), so everything is deleted.
684
685define i9 @fshr_zero_shift_guard_inverted_swapped(i9 %x, i9 %y, i9 %sh) {
686; CHECK-LABEL: @fshr_zero_shift_guard_inverted_swapped(
687; CHECK-NEXT:    ret i9 [[Y:%.*]]
688;
689  %c = icmp ne i9 %sh, 0
690  %f = call i9 @llvm.fshr.i9(i9 %x, i9 %y, i9 %sh)
691  %s = select i1 %c, i9 %y, i9 %f
692  ret i9 %s
693}
694
695; When the shift amount is 0, fshl returns its 1st parameter (x), so the guard is not needed.
696
697define i8 @rotl_zero_shift_guard(i8 %x, i8 %sh) {
698; CHECK-LABEL: @rotl_zero_shift_guard(
699; CHECK-NEXT:    [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[SH:%.*]])
700; CHECK-NEXT:    ret i8 [[F]]
701;
702  %c = icmp eq i8 %sh, 0
703  %f = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %sh)
704  %s = select i1 %c, i8 %x, i8 %f
705  ret i8 %s
706}
707
708; When the shift amount is 0, fshl returns its 1st parameter (x), so the guard is not needed.
709
710define i8 @rotl_zero_shift_guard_swapped(i8 %x, i8 %sh) {
711; CHECK-LABEL: @rotl_zero_shift_guard_swapped(
712; CHECK-NEXT:    [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[SH:%.*]])
713; CHECK-NEXT:    ret i8 [[F]]
714;
715  %c = icmp ne i8 %sh, 0
716  %f = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %sh)
717  %s = select i1 %c, i8 %f, i8 %x
718  ret i8 %s
719}
720
721; When the shift amount is 0, fshl returns its 1st parameter (x), so everything is deleted.
722
723define i8 @rotl_zero_shift_guard_inverted(i8 %x, i8 %sh) {
724; CHECK-LABEL: @rotl_zero_shift_guard_inverted(
725; CHECK-NEXT:    ret i8 [[X:%.*]]
726;
727  %c = icmp eq i8 %sh, 0
728  %f = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %sh)
729  %s = select i1 %c, i8 %f, i8 %x
730  ret i8 %s
731}
732
733; When the shift amount is 0, fshl returns its 1st parameter (x), so everything is deleted.
734
735define i8 @rotl_zero_shift_guard_inverted_swapped(i8 %x, i8 %sh) {
736; CHECK-LABEL: @rotl_zero_shift_guard_inverted_swapped(
737; CHECK-NEXT:    ret i8 [[X:%.*]]
738;
739  %c = icmp ne i8 %sh, 0
740  %f = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %sh)
741  %s = select i1 %c, i8 %x, i8 %f
742  ret i8 %s
743}
744
745; When the shift amount is 0, fshr returns its 2nd parameter (x), so the guard is not needed.
746
747define i9 @rotr_zero_shift_guard(i9 %x, i9 %sh) {
748; CHECK-LABEL: @rotr_zero_shift_guard(
749; CHECK-NEXT:    [[F:%.*]] = call i9 @llvm.fshr.i9(i9 [[X:%.*]], i9 [[X]], i9 [[SH:%.*]])
750; CHECK-NEXT:    ret i9 [[F]]
751;
752  %c = icmp eq i9 %sh, 0
753  %f = call i9 @llvm.fshr.i9(i9 %x, i9 %x, i9 %sh)
754  %s = select i1 %c, i9 %x, i9 %f
755  ret i9 %s
756}
757
758; When the shift amount is 0, fshr returns its 2nd parameter (x), so the guard is not needed.
759
760define i9 @rotr_zero_shift_guard_swapped(i9 %x, i9 %sh) {
761; CHECK-LABEL: @rotr_zero_shift_guard_swapped(
762; CHECK-NEXT:    [[F:%.*]] = call i9 @llvm.fshr.i9(i9 [[X:%.*]], i9 [[X]], i9 [[SH:%.*]])
763; CHECK-NEXT:    ret i9 [[F]]
764;
765  %c = icmp ne i9 %sh, 0
766  %f = call i9 @llvm.fshr.i9(i9 %x, i9 %x, i9 %sh)
767  %s = select i1 %c, i9 %f, i9 %x
768  ret i9 %s
769}
770
771; When the shift amount is 0, fshr returns its 2nd parameter (x), so everything is deleted.
772
773define i9 @rotr_zero_shift_guard_inverted(i9 %x, i9 %sh) {
774; CHECK-LABEL: @rotr_zero_shift_guard_inverted(
775; CHECK-NEXT:    ret i9 [[X:%.*]]
776;
777  %c = icmp eq i9 %sh, 0
778  %f = call i9 @llvm.fshr.i9(i9 %x, i9 %x, i9 %sh)
779  %s = select i1 %c, i9 %f, i9 %x
780  ret i9 %s
781}
782
783; When the shift amount is 0, fshr returns its 2nd parameter (x), so everything is deleted.
784
785define i9 @rotr_zero_shift_guard_inverted_swapped(i9 %x, i9 %sh) {
786; CHECK-LABEL: @rotr_zero_shift_guard_inverted_swapped(
787; CHECK-NEXT:    ret i9 [[X:%.*]]
788;
789  %c = icmp ne i9 %sh, 0
790  %f = call i9 @llvm.fshr.i9(i9 %x, i9 %x, i9 %sh)
791  %s = select i1 %c, i9 %x, i9 %f
792  ret i9 %s
793}
794
795; Negative test - make sure we're matching the correct parameter of fshl.
796
797define i8 @fshl_zero_shift_guard_wrong_select_op(i8 %x, i8 %y, i8 %sh) {
798; CHECK-LABEL: @fshl_zero_shift_guard_wrong_select_op(
799; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[SH:%.*]], 0
800; CHECK-NEXT:    [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[SH]])
801; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i8 [[Y]], i8 [[F]]
802; CHECK-NEXT:    ret i8 [[S]]
803;
804  %c = icmp eq i8 %sh, 0
805  %f = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %sh)
806  %s = select i1 %c, i8 %y, i8 %f
807  ret i8 %s
808}
809
810; Vector types work too.
811
812define <2 x i8> @rotr_zero_shift_guard_splat(<2 x i8> %x, <2 x i8> %sh) {
813; CHECK-LABEL: @rotr_zero_shift_guard_splat(
814; CHECK-NEXT:    [[F:%.*]] = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[X]], <2 x i8> [[SH:%.*]])
815; CHECK-NEXT:    ret <2 x i8> [[F]]
816;
817  %c = icmp eq <2 x i8> %sh, zeroinitializer
818  %f = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> %x, <2 x i8> %x, <2 x i8> %sh)
819  %s = select <2 x i1> %c, <2 x i8> %x, <2 x i8> %f
820  ret <2 x i8> %s
821}
822
823; If first two operands of funnel shift are undef, the result is undef
824
825define i8 @fshl_ops_undef(i8 %shamt) {
826; CHECK-LABEL: @fshl_ops_undef(
827; CHECK-NEXT:    ret i8 undef
828;
829  %r = call i8 @llvm.fshl.i8(i8 undef, i8 undef, i8 %shamt)
830  ret i8 %r
831}
832
833define i9 @fshr_ops_undef(i9 %shamt) {
834; CHECK-LABEL: @fshr_ops_undef(
835; CHECK-NEXT:    ret i9 undef
836;
837  %r = call i9 @llvm.fshr.i9(i9 undef, i9 undef, i9 %shamt)
838  ret i9 %r
839}
840
841; If shift amount is undef, treat it as zero, returning operand 0 or 1
842
843define i8 @fshl_shift_undef(i8 %x, i8 %y) {
844; CHECK-LABEL: @fshl_shift_undef(
845; CHECK-NEXT:    ret i8 [[X:%.*]]
846;
847  %r = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 undef)
848  ret i8 %r
849}
850
851define i9 @fshr_shift_undef(i9 %x, i9 %y) {
852; CHECK-LABEL: @fshr_shift_undef(
853; CHECK-NEXT:    ret i9 [[Y:%.*]]
854;
855  %r = call i9 @llvm.fshr.i9(i9 %x, i9 %y, i9 undef)
856  ret i9 %r
857}
858
859; If one of operands is poison, the result is poison
860; TODO: these should be poison
861define i8 @fshl_ops_poison(i8 %b, i8 %shamt) {
862; CHECK-LABEL: @fshl_ops_poison(
863; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.fshl.i8(i8 poison, i8 [[B:%.*]], i8 [[SHAMT:%.*]])
864; CHECK-NEXT:    ret i8 [[R]]
865;
866  %r = call i8 @llvm.fshl.i8(i8 poison, i8 %b, i8 %shamt)
867  ret i8 %r
868}
869
870define i8 @fshl_ops_poison2(i8 %shamt) {
871; CHECK-LABEL: @fshl_ops_poison2(
872; CHECK-NEXT:    ret i8 undef
873;
874  %r = call i8 @llvm.fshl.i8(i8 poison, i8 undef, i8 %shamt)
875  ret i8 %r
876}
877
878define i8 @fshl_ops_poison3(i8 %a, i8 %shamt) {
879; CHECK-LABEL: @fshl_ops_poison3(
880; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.fshl.i8(i8 [[A:%.*]], i8 poison, i8 [[SHAMT:%.*]])
881; CHECK-NEXT:    ret i8 [[R]]
882;
883  %r = call i8 @llvm.fshl.i8(i8 %a, i8 poison, i8 %shamt)
884  ret i8 %r
885}
886
887define i8 @fshl_ops_poison4(i8 %shamt) {
888; CHECK-LABEL: @fshl_ops_poison4(
889; CHECK-NEXT:    ret i8 undef
890;
891  %r = call i8 @llvm.fshl.i8(i8 undef, i8 poison, i8 %shamt)
892  ret i8 %r
893}
894
895define i8 @fshl_ops_poison5(i8 %a, i8 %b) {
896; CHECK-LABEL: @fshl_ops_poison5(
897; CHECK-NEXT:    ret i8 [[A:%.*]]
898;
899  %r = call i8 @llvm.fshl.i8(i8 %a, i8 %b, i8 poison)
900  ret i8 %r
901}
902
903define i8 @fshl_ops_poison6() {
904; CHECK-LABEL: @fshl_ops_poison6(
905; CHECK-NEXT:    ret i8 undef
906;
907  %r = call i8 @llvm.fshl.i8(i8 undef, i8 undef, i8 poison)
908  ret i8 %r
909}
910
911define i9 @fshr_ops_poison(i9 %b, i9 %shamt) {
912; CHECK-LABEL: @fshr_ops_poison(
913; CHECK-NEXT:    [[R:%.*]] = call i9 @llvm.fshr.i9(i9 poison, i9 [[B:%.*]], i9 [[SHAMT:%.*]])
914; CHECK-NEXT:    ret i9 [[R]]
915;
916  %r = call i9 @llvm.fshr.i9(i9 poison, i9 %b, i9 %shamt)
917  ret i9 %r
918}
919
920define i9 @fshr_ops_poison2(i9 %shamt) {
921; CHECK-LABEL: @fshr_ops_poison2(
922; CHECK-NEXT:    ret i9 undef
923;
924  %r = call i9 @llvm.fshr.i9(i9 poison, i9 undef, i9 %shamt)
925  ret i9 %r
926}
927
928define i9 @fshr_ops_poison3(i9 %a, i9 %shamt) {
929; CHECK-LABEL: @fshr_ops_poison3(
930; CHECK-NEXT:    [[R:%.*]] = call i9 @llvm.fshr.i9(i9 [[A:%.*]], i9 poison, i9 [[SHAMT:%.*]])
931; CHECK-NEXT:    ret i9 [[R]]
932;
933  %r = call i9 @llvm.fshr.i9(i9 %a, i9 poison, i9 %shamt)
934  ret i9 %r
935}
936
937define i9 @fshr_ops_poison4(i9 %shamt) {
938; CHECK-LABEL: @fshr_ops_poison4(
939; CHECK-NEXT:    ret i9 undef
940;
941  %r = call i9 @llvm.fshr.i9(i9 undef, i9 poison, i9 %shamt)
942  ret i9 %r
943}
944
945define i9 @fshr_ops_poison5(i9 %a, i9 %b) {
946; CHECK-LABEL: @fshr_ops_poison5(
947; CHECK-NEXT:    ret i9 [[B:%.*]]
948;
949  %r = call i9 @llvm.fshr.i9(i9 %a, i9 %b, i9 poison)
950  ret i9 %r
951}
952
953define i9 @fshr_ops_poison6() {
954; CHECK-LABEL: @fshr_ops_poison6(
955; CHECK-NEXT:    ret i9 undef
956;
957  %r = call i9 @llvm.fshr.i9(i9 undef, i9 undef, i9 poison)
958  ret i9 %r
959}
960
961declare double @llvm.fma.f64(double,double,double)
962declare double @llvm.fmuladd.f64(double,double,double)
963
964define double @fma_undef_op0(double %x, double %y) {
965; CHECK-LABEL: @fma_undef_op0(
966; CHECK-NEXT:    ret double 0x7FF8000000000000
967;
968  %r = call double @llvm.fma.f64(double undef, double %x, double %y)
969  ret double %r
970}
971
972define double @fma_poison_op0(double %x, double %y) {
973; CHECK-LABEL: @fma_poison_op0(
974; CHECK-NEXT:    ret double poison
975;
976  %r = call double @llvm.fma.f64(double poison, double %x, double %y)
977  ret double %r
978}
979
980define double @fma_undef_op1(double %x, double %y) {
981; CHECK-LABEL: @fma_undef_op1(
982; CHECK-NEXT:    ret double 0x7FF8000000000000
983;
984  %r = call double @llvm.fma.f64(double %x, double undef, double %y)
985  ret double %r
986}
987
988define double @fma_poison_op1(double %x, double %y) {
989; CHECK-LABEL: @fma_poison_op1(
990; CHECK-NEXT:    ret double poison
991;
992  %r = call double @llvm.fma.f64(double %x, double poison, double %y)
993  ret double %r
994}
995
996define double @fma_undef_op2(double %x, double %y) {
997; CHECK-LABEL: @fma_undef_op2(
998; CHECK-NEXT:    ret double 0x7FF8000000000000
999;
1000  %r = call double @llvm.fma.f64(double %x, double %y, double undef)
1001  ret double %r
1002}
1003
1004define double @fma_poison_op2(double %x, double %y) {
1005; CHECK-LABEL: @fma_poison_op2(
1006; CHECK-NEXT:    ret double poison
1007;
1008  %r = call double @llvm.fma.f64(double %x, double %y, double poison)
1009  ret double %r
1010}
1011
1012define double @fmuladd_undef_op0(double %x, double %y) {
1013; CHECK-LABEL: @fmuladd_undef_op0(
1014; CHECK-NEXT:    ret double 0x7FF8000000000000
1015;
1016  %r = call double @llvm.fmuladd.f64(double undef, double %x, double %y)
1017  ret double %r
1018}
1019
1020define double @fmuladd_poison_op0(double %x, double %y) {
1021; CHECK-LABEL: @fmuladd_poison_op0(
1022; CHECK-NEXT:    ret double poison
1023;
1024  %r = call double @llvm.fmuladd.f64(double poison, double %x, double %y)
1025  ret double %r
1026}
1027
1028define double @fmuladd_undef_op1(double %x, double %y) {
1029; CHECK-LABEL: @fmuladd_undef_op1(
1030; CHECK-NEXT:    ret double 0x7FF8000000000000
1031;
1032  %r = call double @llvm.fmuladd.f64(double %x, double undef, double %y)
1033  ret double %r
1034}
1035
1036define double @fmuladd_poison_op1(double %x, double %y) {
1037; CHECK-LABEL: @fmuladd_poison_op1(
1038; CHECK-NEXT:    ret double poison
1039;
1040  %r = call double @llvm.fmuladd.f64(double %x, double poison, double %y)
1041  ret double %r
1042}
1043
1044define double @fmuladd_undef_op2(double %x, double %y) {
1045; CHECK-LABEL: @fmuladd_undef_op2(
1046; CHECK-NEXT:    ret double 0x7FF8000000000000
1047;
1048  %r = call double @llvm.fmuladd.f64(double %x, double %y, double undef)
1049  ret double %r
1050}
1051
1052define double @fmuladd_poison_op2(double %x, double %y) {
1053; CHECK-LABEL: @fmuladd_poison_op2(
1054; CHECK-NEXT:    ret double poison
1055;
1056  %r = call double @llvm.fmuladd.f64(double %x, double %y, double poison)
1057  ret double %r
1058}
1059
1060define double @fma_nan_op0(double %x, double %y) {
1061; CHECK-LABEL: @fma_nan_op0(
1062; CHECK-NEXT:    ret double 0x7FF8000000000000
1063;
1064  %r = call double @llvm.fma.f64(double 0x7ff8000000000000, double %x, double %y)
1065  ret double %r
1066}
1067
1068define double @fma_nan_op1(double %x, double %y) {
1069; CHECK-LABEL: @fma_nan_op1(
1070; CHECK-NEXT:    ret double 0x7FF8000000000001
1071;
1072  %r = call double @llvm.fma.f64(double %x, double 0x7ff8000000000001, double %y)
1073  ret double %r
1074}
1075
1076define double @fma_nan_op2(double %x, double %y) {
1077; CHECK-LABEL: @fma_nan_op2(
1078; CHECK-NEXT:    ret double 0x7FF8000000000002
1079;
1080  %r = call double @llvm.fma.f64(double %x, double %y, double 0x7ff8000000000002)
1081  ret double %r
1082}
1083
1084define double @fmuladd_nan_op0_op1(double %x) {
1085; CHECK-LABEL: @fmuladd_nan_op0_op1(
1086; CHECK-NEXT:    ret double 0x7FF8000000001234
1087;
1088  %r = call double @llvm.fmuladd.f64(double 0x7ff8000000001234, double 0x7ff800000000dead, double %x)
1089  ret double %r
1090}
1091
1092define double @fmuladd_nan_op0_op2(double %x) {
1093; CHECK-LABEL: @fmuladd_nan_op0_op2(
1094; CHECK-NEXT:    ret double 0x7FF8000000005678
1095;
1096  %r = call double @llvm.fmuladd.f64(double 0x7ff8000000005678, double %x, double 0x7ff800000000dead)
1097  ret double %r
1098}
1099
1100define double @fmuladd_nan_op1_op2(double %x) {
1101; CHECK-LABEL: @fmuladd_nan_op1_op2(
1102; CHECK-NEXT:    ret double 0x7FF80000AAAAAAAA
1103;
1104  %r = call double @llvm.fmuladd.f64(double %x, double 0x7ff80000aaaaaaaa, double 0x7ff800000000dead)
1105  ret double %r
1106}
1107
1108define double @fma_nan_multiplicand_inf_zero(double %x) {
1109; CHECK-LABEL: @fma_nan_multiplicand_inf_zero(
1110; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double 0x7FF0000000000000, double 0.000000e+00, double [[X:%.*]])
1111; CHECK-NEXT:    ret double [[R]]
1112;
1113  %r = call double @llvm.fma.f64(double 0x7ff0000000000000, double 0.0, double %x)
1114  ret double %r
1115}
1116
1117define double @fma_nan_multiplicand_zero_inf(double %x) {
1118; CHECK-LABEL: @fma_nan_multiplicand_zero_inf(
1119; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double 0.000000e+00, double 0x7FF0000000000000, double [[X:%.*]])
1120; CHECK-NEXT:    ret double [[R]]
1121;
1122  %r = call double @llvm.fma.f64(double 0.0, double 0x7ff0000000000000, double %x)
1123  ret double %r
1124}
1125
1126define double @fma_nan_addend_inf_neginf(double %x, i32 %y) {
1127; CHECK-LABEL: @fma_nan_addend_inf_neginf(
1128; CHECK-NEXT:    [[NOTNAN:%.*]] = uitofp i32 [[Y:%.*]] to double
1129; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double 0x7FF0000000000000, double [[NOTNAN]], double 0xFFF0000000000000)
1130; CHECK-NEXT:    ret double [[R]]
1131;
1132  %notnan = uitofp i32 %y to double
1133  %r = call double @llvm.fma.f64(double 0x7ff0000000000000, double %notnan, double 0xfff0000000000000)
1134  ret double %r
1135}
1136
1137define double @fma_nan_addend_neginf_inf(double %x, i1 %y) {
1138; CHECK-LABEL: @fma_nan_addend_neginf_inf(
1139; CHECK-NEXT:    [[NOTNAN:%.*]] = select i1 [[Y:%.*]], double 4.200000e+01, double -1.000000e-01
1140; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double [[NOTNAN]], double 0xFFF0000000000000, double 0x7FF0000000000000)
1141; CHECK-NEXT:    ret double [[R]]
1142;
1143  %notnan = select i1 %y, double 42.0, double -0.1
1144  %r = call double @llvm.fma.f64(double %notnan, double 0xfff0000000000000, double 0x7ff0000000000000)
1145  ret double %r
1146}
1147
1148define double @fmuladd_nan_multiplicand_neginf_zero(double %x) {
1149; CHECK-LABEL: @fmuladd_nan_multiplicand_neginf_zero(
1150; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double 0xFFF0000000000000, double 0.000000e+00, double [[X:%.*]])
1151; CHECK-NEXT:    ret double [[R]]
1152;
1153  %r = call double @llvm.fmuladd.f64(double 0xfff0000000000000, double 0.0, double %x)
1154  ret double %r
1155}
1156
1157define double @fmuladd_nan_multiplicand_negzero_inf(double %x) {
1158; CHECK-LABEL: @fmuladd_nan_multiplicand_negzero_inf(
1159; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double -0.000000e+00, double 0x7FF0000000000000, double [[X:%.*]])
1160; CHECK-NEXT:    ret double [[R]]
1161;
1162  %r = call double @llvm.fmuladd.f64(double -0.0, double 0x7ff0000000000000, double %x)
1163  ret double %r
1164}
1165
1166define double @fmuladd_nan_addend_inf_neginf(double %x, i32 %y) {
1167; CHECK-LABEL: @fmuladd_nan_addend_inf_neginf(
1168; CHECK-NEXT:    [[NOTNAN:%.*]] = sitofp i32 [[Y:%.*]] to double
1169; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double 0x7FF0000000000000, double [[NOTNAN]], double 0xFFF0000000000000)
1170; CHECK-NEXT:    ret double [[R]]
1171;
1172  %notnan = sitofp i32 %y to double
1173  %r = call double @llvm.fmuladd.f64(double 0x7ff0000000000000, double %notnan, double 0xfff0000000000000)
1174  ret double %r
1175}
1176
1177define double @fmuladd_nan_addend_neginf_inf(double %x, i1 %y) {
1178; CHECK-LABEL: @fmuladd_nan_addend_neginf_inf(
1179; CHECK-NEXT:    [[NOTNAN:%.*]] = select i1 [[Y:%.*]], double 4.200000e+01, double -1.000000e-01
1180; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double [[NOTNAN]], double 0xFFF0000000000000, double 0x7FF0000000000000)
1181; CHECK-NEXT:    ret double [[R]]
1182;
1183  %notnan = select i1 %y, double 42.0, double -0.1
1184  %r = call double @llvm.fmuladd.f64(double %notnan, double 0xfff0000000000000, double 0x7ff0000000000000)
1185  ret double %r
1186}
1187
1188declare float @llvm.copysign.f32(float, float)
1189declare <2 x double> @llvm.copysign.v2f64(<2 x double>, <2 x double>)
1190
1191define float @copysign_same_operand(float %x) {
1192; CHECK-LABEL: @copysign_same_operand(
1193; CHECK-NEXT:    ret float [[X:%.*]]
1194;
1195  %r = call float @llvm.copysign.f32(float %x, float %x)
1196  ret float %r
1197}
1198
1199define <2 x double> @copysign_same_operand_vec(<2 x double> %x) {
1200; CHECK-LABEL: @copysign_same_operand_vec(
1201; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
1202;
1203  %r = call <2 x double> @llvm.copysign.v2f64(<2 x double> %x, <2 x double> %x)
1204  ret <2 x double> %r
1205}
1206
1207define float @negated_sign_arg(float %x) {
1208; CHECK-LABEL: @negated_sign_arg(
1209; CHECK-NEXT:    [[NEGX:%.*]] = fsub ninf float -0.000000e+00, [[X:%.*]]
1210; CHECK-NEXT:    ret float [[NEGX]]
1211;
1212  %negx = fsub ninf float -0.0, %x
1213  %r = call arcp float @llvm.copysign.f32(float %x, float %negx)
1214  ret float %r
1215}
1216
1217define <2 x double> @negated_sign_arg_vec(<2 x double> %x) {
1218; CHECK-LABEL: @negated_sign_arg_vec(
1219; CHECK-NEXT:    [[NEGX:%.*]] = fneg afn <2 x double> [[X:%.*]]
1220; CHECK-NEXT:    ret <2 x double> [[NEGX]]
1221;
1222  %negx = fneg afn <2 x double> %x
1223  %r = call arcp <2 x double> @llvm.copysign.v2f64(<2 x double> %x, <2 x double> %negx)
1224  ret <2 x double> %r
1225}
1226
1227define float @negated_mag_arg(float %x) {
1228; CHECK-LABEL: @negated_mag_arg(
1229; CHECK-NEXT:    ret float [[X:%.*]]
1230;
1231  %negx = fneg nnan float %x
1232  %r = call ninf float @llvm.copysign.f32(float %negx, float %x)
1233  ret float %r
1234}
1235
1236define <2 x double> @negated_mag_arg_vec(<2 x double> %x) {
1237; CHECK-LABEL: @negated_mag_arg_vec(
1238; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
1239;
1240  %negx = fneg afn <2 x double> %x
1241  %r = call arcp <2 x double> @llvm.copysign.v2f64(<2 x double> %negx, <2 x double> %x)
1242  ret <2 x double> %r
1243}
1244
1245; We handle the "returned" attribute only in InstCombine, because the fact
1246; that this simplification may replace one call with another may cause issues
1247; for call graph passes.
1248
1249declare i32 @passthru_i32(i32 returned)
1250declare i8* @passthru_p8(i8* returned)
1251
1252define i32 @returned_const_int_arg() {
1253; CHECK-LABEL: @returned_const_int_arg(
1254; CHECK-NEXT:    [[X:%.*]] = call i32 @passthru_i32(i32 42)
1255; CHECK-NEXT:    ret i32 [[X]]
1256;
1257  %x = call i32 @passthru_i32(i32 42)
1258  ret i32 %x
1259}
1260
1261define i8* @returned_const_ptr_arg() {
1262; CHECK-LABEL: @returned_const_ptr_arg(
1263; CHECK-NEXT:    [[X:%.*]] = call i8* @passthru_p8(i8* null)
1264; CHECK-NEXT:    ret i8* [[X]]
1265;
1266  %x = call i8* @passthru_p8(i8* null)
1267  ret i8* %x
1268}
1269
1270define i32 @returned_var_arg(i32 %arg) {
1271; CHECK-LABEL: @returned_var_arg(
1272; CHECK-NEXT:    [[X:%.*]] = call i32 @passthru_i32(i32 [[ARG:%.*]])
1273; CHECK-NEXT:    ret i32 [[X]]
1274;
1275  %x = call i32 @passthru_i32(i32 %arg)
1276  ret i32 %x
1277}
1278
1279define i32 @returned_const_int_arg_musttail(i32 %arg) {
1280; CHECK-LABEL: @returned_const_int_arg_musttail(
1281; CHECK-NEXT:    [[X:%.*]] = musttail call i32 @passthru_i32(i32 42)
1282; CHECK-NEXT:    ret i32 [[X]]
1283;
1284  %x = musttail call i32 @passthru_i32(i32 42)
1285  ret i32 %x
1286}
1287
1288define i32 @returned_var_arg_musttail(i32 %arg) {
1289; CHECK-LABEL: @returned_var_arg_musttail(
1290; CHECK-NEXT:    [[X:%.*]] = musttail call i32 @passthru_i32(i32 [[ARG:%.*]])
1291; CHECK-NEXT:    ret i32 [[X]]
1292;
1293  %x = musttail call i32 @passthru_i32(i32 %arg)
1294  ret i32 %x
1295}
1296
1297define i32 @call_undef_musttail() {
1298; CHECK-LABEL: @call_undef_musttail(
1299; CHECK-NEXT:    [[X:%.*]] = musttail call i32 undef()
1300; CHECK-NEXT:    ret i32 [[X]]
1301;
1302  %x = musttail call i32 undef()
1303  ret i32 %x
1304}
1305
1306; This is not the builtin fmax, so we don't know anything about its behavior.
1307
1308declare float @fmaxf(float, float)
1309
1310define float @nobuiltin_fmax() {
1311; CHECK-LABEL: @nobuiltin_fmax(
1312; CHECK-NEXT:    [[M:%.*]] = call float @fmaxf(float 0.000000e+00, float 1.000000e+00) #[[ATTR3:[0-9]+]]
1313; CHECK-NEXT:    [[R:%.*]] = call float @llvm.fabs.f32(float [[M]])
1314; CHECK-NEXT:    ret float [[R]]
1315;
1316  %m = call float @fmaxf(float 0.0, float 1.0) #0
1317  %r = call float @llvm.fabs.f32(float %m)
1318  ret float %r
1319}
1320
1321
1322declare i32 @llvm.ctpop.i32(i32)
1323declare <3 x i33> @llvm.ctpop.v3i33(<3 x i33>)
1324declare i1 @llvm.ctpop.i1(i1)
1325
1326define i32 @ctpop_lowbit(i32 %x) {
1327; CHECK-LABEL: @ctpop_lowbit(
1328; CHECK-NEXT:    [[B:%.*]] = and i32 [[X:%.*]], 1
1329; CHECK-NEXT:    ret i32 [[B]]
1330;
1331  %b = and i32 %x, 1
1332  %r = call i32 @llvm.ctpop.i32(i32 %b)
1333  ret i32 %r
1334}
1335
1336; Negative test - only low bit allowed
1337; This could be reduced by instcombine to and+shift.
1338
1339define i32 @ctpop_pow2(i32 %x) {
1340; CHECK-LABEL: @ctpop_pow2(
1341; CHECK-NEXT:    [[B:%.*]] = and i32 [[X:%.*]], 4
1342; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.ctpop.i32(i32 [[B]])
1343; CHECK-NEXT:    ret i32 [[R]]
1344;
1345  %b = and i32 %x, 4
1346  %r = call i32 @llvm.ctpop.i32(i32 %b)
1347  ret i32 %r
1348}
1349
1350define <3 x i33> @ctpop_signbit(<3 x i33> %x) {
1351; CHECK-LABEL: @ctpop_signbit(
1352; CHECK-NEXT:    [[B:%.*]] = lshr <3 x i33> [[X:%.*]], <i33 32, i33 32, i33 32>
1353; CHECK-NEXT:    ret <3 x i33> [[B]]
1354;
1355  %b = lshr <3 x i33> %x, <i33 32, i33 32, i33 32>
1356  %r = tail call <3 x i33> @llvm.ctpop.v3i33(<3 x i33> %b)
1357  ret <3 x i33> %r
1358}
1359
1360; Negative test - only 1 bit allowed
1361
1362define <3 x i33> @ctpop_notsignbit(<3 x i33> %x) {
1363; CHECK-LABEL: @ctpop_notsignbit(
1364; CHECK-NEXT:    [[B:%.*]] = lshr <3 x i33> [[X:%.*]], <i33 31, i33 31, i33 31>
1365; CHECK-NEXT:    [[R:%.*]] = tail call <3 x i33> @llvm.ctpop.v3i33(<3 x i33> [[B]])
1366; CHECK-NEXT:    ret <3 x i33> [[R]]
1367;
1368  %b = lshr <3 x i33> %x, <i33 31, i33 31, i33 31>
1369  %r = tail call <3 x i33> @llvm.ctpop.v3i33(<3 x i33> %b)
1370  ret <3 x i33> %r
1371}
1372
1373define i1 @ctpop_bool(i1 %x) {
1374; CHECK-LABEL: @ctpop_bool(
1375; CHECK-NEXT:    ret i1 [[X:%.*]]
1376;
1377  %r = tail call i1 @llvm.ctpop.i1(i1 %x)
1378  ret i1 %r
1379}
1380
1381declare i32 @llvm.cttz.i32(i32, i1)
1382declare <3 x i33> @llvm.cttz.v3i33(<3 x i33>, i1)
1383
1384define i32 @cttz_shl1(i32 %x) {
1385; CHECK-LABEL: @cttz_shl1(
1386; CHECK-NEXT:    ret i32 [[X:%.*]]
1387;
1388  %s = shl i32 1, %x
1389  %r = call i32 @llvm.cttz.i32(i32 %s, i1 true)
1390  ret i32 %r
1391}
1392
1393define <3 x i33> @cttz_shl1_vec(<3 x i33> %x) {
1394; CHECK-LABEL: @cttz_shl1_vec(
1395; CHECK-NEXT:    ret <3 x i33> [[X:%.*]]
1396;
1397  %s = shl <3 x i33> <i33 1, i33 1, i33 undef>, %x
1398  %r = call <3 x i33> @llvm.cttz.v3i33(<3 x i33> %s, i1 false)
1399  ret <3 x i33> %r
1400}
1401
1402; Negative test - this could be generalized in instcombine though.
1403
1404define i32 @cttz_shl_not_low_bit(i32 %x) {
1405; CHECK-LABEL: @cttz_shl_not_low_bit(
1406; CHECK-NEXT:    [[S:%.*]] = shl i32 2, [[X:%.*]]
1407; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.cttz.i32(i32 [[S]], i1 true)
1408; CHECK-NEXT:    ret i32 [[R]]
1409;
1410  %s = shl i32 2, %x
1411  %r = call i32 @llvm.cttz.i32(i32 %s, i1 true)
1412  ret i32 %r
1413}
1414
1415declare i32 @llvm.ctlz.i32(i32, i1)
1416declare <3 x i33> @llvm.ctlz.v3i33(<3 x i33>, i1)
1417
1418define i32 @ctlz_lshr_sign_bit(i32 %x) {
1419; CHECK-LABEL: @ctlz_lshr_sign_bit(
1420; CHECK-NEXT:    ret i32 [[X:%.*]]
1421;
1422  %s = lshr i32 2147483648, %x
1423  %r = call i32 @llvm.ctlz.i32(i32 %s, i1 true)
1424  ret i32 %r
1425}
1426
1427define i32 @ctlz_lshr_negative(i32 %x) {
1428; CHECK-LABEL: @ctlz_lshr_negative(
1429; CHECK-NEXT:    ret i32 [[X:%.*]]
1430;
1431  %s = lshr i32 -42, %x
1432  %r = call i32 @llvm.ctlz.i32(i32 %s, i1 true)
1433  ret i32 %r
1434}
1435
1436define <3 x i33> @ctlz_lshr_sign_bit_vec(<3 x i33> %x) {
1437; CHECK-LABEL: @ctlz_lshr_sign_bit_vec(
1438; CHECK-NEXT:    ret <3 x i33> [[X:%.*]]
1439;
1440  %s = lshr <3 x i33> <i33 undef, i33 4294967296, i33 4294967296>, %x
1441  %r = call <3 x i33> @llvm.ctlz.v3i33(<3 x i33> %s, i1 false)
1442  ret <3 x i33> %r
1443}
1444
1445; Negative test - this could be generalized in instcombine though.
1446
1447define i32 @ctlz_lshr_not_negative(i32 %x) {
1448; CHECK-LABEL: @ctlz_lshr_not_negative(
1449; CHECK-NEXT:    [[S:%.*]] = lshr i32 42, [[X:%.*]]
1450; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.ctlz.i32(i32 [[S]], i1 true)
1451; CHECK-NEXT:    ret i32 [[R]]
1452;
1453  %s = lshr i32 42, %x
1454  %r = call i32 @llvm.ctlz.i32(i32 %s, i1 true)
1455  ret i32 %r
1456}
1457
1458define i32 @ctlz_ashr_sign_bit(i32 %x) {
1459; CHECK-LABEL: @ctlz_ashr_sign_bit(
1460; CHECK-NEXT:    ret i32 0
1461;
1462  %s = ashr i32 2147483648, %x
1463  %r = call i32 @llvm.ctlz.i32(i32 %s, i1 false)
1464  ret i32 %r
1465}
1466
1467define i32 @ctlz_ashr_negative(i32 %x) {
1468; CHECK-LABEL: @ctlz_ashr_negative(
1469; CHECK-NEXT:    ret i32 0
1470;
1471  %s = ashr i32 -42, %x
1472  %r = call i32 @llvm.ctlz.i32(i32 %s, i1 false)
1473  ret i32 %r
1474}
1475
1476define <3 x i33> @ctlz_ashr_sign_bit_vec(<3 x i33> %x) {
1477; CHECK-LABEL: @ctlz_ashr_sign_bit_vec(
1478; CHECK-NEXT:    ret <3 x i33> zeroinitializer
1479;
1480  %s = ashr <3 x i33> <i33 4294967296, i33 undef, i33 4294967296>, %x
1481  %r = call <3 x i33> @llvm.ctlz.v3i33(<3 x i33> %s, i1 true)
1482  ret <3 x i33> %r
1483}
1484
1485attributes #0 = { nobuiltin readnone }
1486