[mlir][TableGen] Support intrinsics with multiple returns and overloaded operands.
[lldb.git] / mlir / test / Target / llvmir-intrinsics.mlir
1 // RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
2
3 // CHECK-LABEL: @intrinsics
4 llvm.func @intrinsics(%arg0: !llvm.float, %arg1: !llvm.float, %arg2: !llvm.vec<8 x float>, %arg3: !llvm.ptr<i8>) {
5   %c3 = llvm.mlir.constant(3 : i32) : !llvm.i32
6   %c1 = llvm.mlir.constant(1 : i32) : !llvm.i32
7   %c0 = llvm.mlir.constant(0 : i32) : !llvm.i32
8   // CHECK: call float @llvm.fmuladd.f32
9   "llvm.intr.fmuladd"(%arg0, %arg1, %arg0) : (!llvm.float, !llvm.float, !llvm.float) -> !llvm.float
10   // CHECK: call <8 x float> @llvm.fmuladd.v8f32
11   "llvm.intr.fmuladd"(%arg2, %arg2, %arg2) : (!llvm.vec<8 x float>, !llvm.vec<8 x float>, !llvm.vec<8 x float>) -> !llvm.vec<8 x float>
12   // CHECK: call float @llvm.fma.f32
13   "llvm.intr.fma"(%arg0, %arg1, %arg0) : (!llvm.float, !llvm.float, !llvm.float) -> !llvm.float
14   // CHECK: call <8 x float> @llvm.fma.v8f32
15   "llvm.intr.fma"(%arg2, %arg2, %arg2) : (!llvm.vec<8 x float>, !llvm.vec<8 x float>, !llvm.vec<8 x float>) -> !llvm.vec<8 x float>
16   // CHECK: call void @llvm.prefetch.p0i8(i8* %3, i32 0, i32 3, i32 1)
17   "llvm.intr.prefetch"(%arg3, %c0, %c3, %c1) : (!llvm.ptr<i8>, !llvm.i32, !llvm.i32, !llvm.i32) -> ()
18   llvm.return
19 }
20
21 // CHECK-LABEL: @exp_test
22 llvm.func @exp_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
23   // CHECK: call float @llvm.exp.f32
24   "llvm.intr.exp"(%arg0) : (!llvm.float) -> !llvm.float
25   // CHECK: call <8 x float> @llvm.exp.v8f32
26   "llvm.intr.exp"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
27   llvm.return
28 }
29
30 // CHECK-LABEL: @exp2_test
31 llvm.func @exp2_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
32   // CHECK: call float @llvm.exp2.f32
33   "llvm.intr.exp2"(%arg0) : (!llvm.float) -> !llvm.float
34   // CHECK: call <8 x float> @llvm.exp2.v8f32
35   "llvm.intr.exp2"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
36   llvm.return
37 }
38
39 // CHECK-LABEL: @log_test
40 llvm.func @log_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
41   // CHECK: call float @llvm.log.f32
42   "llvm.intr.log"(%arg0) : (!llvm.float) -> !llvm.float
43   // CHECK: call <8 x float> @llvm.log.v8f32
44   "llvm.intr.log"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
45   llvm.return
46 }
47
48 // CHECK-LABEL: @log10_test
49 llvm.func @log10_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
50   // CHECK: call float @llvm.log10.f32
51   "llvm.intr.log10"(%arg0) : (!llvm.float) -> !llvm.float
52   // CHECK: call <8 x float> @llvm.log10.v8f32
53   "llvm.intr.log10"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
54   llvm.return
55 }
56
57 // CHECK-LABEL: @log2_test
58 llvm.func @log2_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
59   // CHECK: call float @llvm.log2.f32
60   "llvm.intr.log2"(%arg0) : (!llvm.float) -> !llvm.float
61   // CHECK: call <8 x float> @llvm.log2.v8f32
62   "llvm.intr.log2"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
63   llvm.return
64 }
65
66 // CHECK-LABEL: @fabs_test
67 llvm.func @fabs_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
68   // CHECK: call float @llvm.fabs.f32
69   "llvm.intr.fabs"(%arg0) : (!llvm.float) -> !llvm.float
70   // CHECK: call <8 x float> @llvm.fabs.v8f32
71   "llvm.intr.fabs"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
72   llvm.return
73 }
74
75 // CHECK-LABEL: @sqrt_test
76 llvm.func @sqrt_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
77   // CHECK: call float @llvm.sqrt.f32
78   "llvm.intr.sqrt"(%arg0) : (!llvm.float) -> !llvm.float
79   // CHECK: call <8 x float> @llvm.sqrt.v8f32
80   "llvm.intr.sqrt"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
81   llvm.return
82 }
83
84 // CHECK-LABEL: @ceil_test
85 llvm.func @ceil_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
86   // CHECK: call float @llvm.ceil.f32
87   "llvm.intr.ceil"(%arg0) : (!llvm.float) -> !llvm.float
88   // CHECK: call <8 x float> @llvm.ceil.v8f32
89   "llvm.intr.ceil"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
90   llvm.return
91 }
92
93 // CHECK-LABEL: @floor_test
94 llvm.func @floor_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
95   // CHECK: call float @llvm.floor.f32
96   "llvm.intr.floor"(%arg0) : (!llvm.float) -> !llvm.float
97   // CHECK: call <8 x float> @llvm.floor.v8f32
98   "llvm.intr.floor"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
99   llvm.return
100 }
101
102 // CHECK-LABEL: @cos_test
103 llvm.func @cos_test(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>) {
104   // CHECK: call float @llvm.cos.f32
105   "llvm.intr.cos"(%arg0) : (!llvm.float) -> !llvm.float
106   // CHECK: call <8 x float> @llvm.cos.v8f32
107   "llvm.intr.cos"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.vec<8 x float>
108   llvm.return
109 }
110
111 // CHECK-LABEL: @copysign_test
112 llvm.func @copysign_test(%arg0: !llvm.float, %arg1: !llvm.float, %arg2: !llvm.vec<8 x float>, %arg3: !llvm.vec<8 x float>) {
113   // CHECK: call float @llvm.copysign.f32
114   "llvm.intr.copysign"(%arg0, %arg1) : (!llvm.float, !llvm.float) -> !llvm.float
115   // CHECK: call <8 x float> @llvm.copysign.v8f32
116   "llvm.intr.copysign"(%arg2, %arg3) : (!llvm.vec<8 x float>, !llvm.vec<8 x float>) -> !llvm.vec<8 x float>
117   llvm.return
118 }
119
120 // CHECK-LABEL: @pow_test
121 llvm.func @pow_test(%arg0: !llvm.float, %arg1: !llvm.float, %arg2: !llvm.vec<8 x float>, %arg3: !llvm.vec<8 x float>) {
122   // CHECK: call float @llvm.pow.f32
123   "llvm.intr.pow"(%arg0, %arg1) : (!llvm.float, !llvm.float) -> !llvm.float
124   // CHECK: call <8 x float> @llvm.pow.v8f32
125   "llvm.intr.pow"(%arg2, %arg3) : (!llvm.vec<8 x float>, !llvm.vec<8 x float>) -> !llvm.vec<8 x float>
126   llvm.return
127 }
128
129 // CHECK-LABEL: @bitreverse_test
130 llvm.func @bitreverse_test(%arg0: !llvm.i32, %arg1: !llvm.vec<8 x i32>) {
131   // CHECK: call i32 @llvm.bitreverse.i32
132   "llvm.intr.bitreverse"(%arg0) : (!llvm.i32) -> !llvm.i32
133   // CHECK: call <8 x i32> @llvm.bitreverse.v8i32
134   "llvm.intr.bitreverse"(%arg1) : (!llvm.vec<8 x i32>) -> !llvm.vec<8 x i32>
135   llvm.return
136 }
137
138 // CHECK-LABEL: @ctpop_test
139 llvm.func @ctpop_test(%arg0: !llvm.i32, %arg1: !llvm.vec<8 x i32>) {
140   // CHECK: call i32 @llvm.ctpop.i32
141   "llvm.intr.ctpop"(%arg0) : (!llvm.i32) -> !llvm.i32
142   // CHECK: call <8 x i32> @llvm.ctpop.v8i32
143   "llvm.intr.ctpop"(%arg1) : (!llvm.vec<8 x i32>) -> !llvm.vec<8 x i32>
144   llvm.return
145 }
146
147 // CHECK-LABEL: @maxnum_test
148 llvm.func @maxnum_test(%arg0: !llvm.float, %arg1: !llvm.float, %arg2: !llvm.vec<8 x float>, %arg3: !llvm.vec<8 x float>) {
149   // CHECK: call float @llvm.maxnum.f32
150   "llvm.intr.maxnum"(%arg0, %arg1) : (!llvm.float, !llvm.float) -> !llvm.float
151   // CHECK: call <8 x float> @llvm.maxnum.v8f32
152   "llvm.intr.maxnum"(%arg2, %arg3) : (!llvm.vec<8 x float>, !llvm.vec<8 x float>) -> !llvm.vec<8 x float>
153   llvm.return
154 }
155
156 // CHECK-LABEL: @minnum_test
157 llvm.func @minnum_test(%arg0: !llvm.float, %arg1: !llvm.float, %arg2: !llvm.vec<8 x float>, %arg3: !llvm.vec<8 x float>) {
158   // CHECK: call float @llvm.minnum.f32
159   "llvm.intr.minnum"(%arg0, %arg1) : (!llvm.float, !llvm.float) -> !llvm.float
160   // CHECK: call <8 x float> @llvm.minnum.v8f32
161   "llvm.intr.minnum"(%arg2, %arg3) : (!llvm.vec<8 x float>, !llvm.vec<8 x float>) -> !llvm.vec<8 x float>
162   llvm.return
163 }
164
165 // CHECK-LABEL: @smax_test
166 llvm.func @smax_test(%arg0: !llvm.i32, %arg1: !llvm.i32, %arg2: !llvm.vec<8 x i32>, %arg3: !llvm.vec<8 x i32>) {
167   // CHECK: call i32 @llvm.smax.i32
168   "llvm.intr.smax"(%arg0, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.i32
169   // CHECK: call <8 x i32> @llvm.smax.v8i32
170   "llvm.intr.smax"(%arg2, %arg3) : (!llvm.vec<8 x i32>, !llvm.vec<8 x i32>) -> !llvm.vec<8 x i32>
171   llvm.return
172 }
173
174 // CHECK-LABEL: @smin_test
175 llvm.func @smin_test(%arg0: !llvm.i32, %arg1: !llvm.i32, %arg2: !llvm.vec<8 x i32>, %arg3: !llvm.vec<8 x i32>) {
176   // CHECK: call i32 @llvm.smin.i32
177   "llvm.intr.smin"(%arg0, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.i32
178   // CHECK: call <8 x i32> @llvm.smin.v8i32
179   "llvm.intr.smin"(%arg2, %arg3) : (!llvm.vec<8 x i32>, !llvm.vec<8 x i32>) -> !llvm.vec<8 x i32>
180   llvm.return
181 }
182
183 // CHECK-LABEL: @vector_reductions
184 llvm.func @vector_reductions(%arg0: !llvm.float, %arg1: !llvm.vec<8 x float>, %arg2: !llvm.vec<8 x i32>) {
185   // CHECK: call i32 @llvm.vector.reduce.add.v8i32
186   "llvm.intr.vector.reduce.add"(%arg2) : (!llvm.vec<8 x i32>) -> !llvm.i32
187   // CHECK: call i32 @llvm.vector.reduce.and.v8i32
188   "llvm.intr.vector.reduce.and"(%arg2) : (!llvm.vec<8 x i32>) -> !llvm.i32
189   // CHECK: call float @llvm.vector.reduce.fmax.v8f32
190   "llvm.intr.vector.reduce.fmax"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.float
191   // CHECK: call float @llvm.vector.reduce.fmin.v8f32
192   "llvm.intr.vector.reduce.fmin"(%arg1) : (!llvm.vec<8 x float>) -> !llvm.float
193   // CHECK: call i32 @llvm.vector.reduce.mul.v8i32
194   "llvm.intr.vector.reduce.mul"(%arg2) : (!llvm.vec<8 x i32>) -> !llvm.i32
195   // CHECK: call i32 @llvm.vector.reduce.or.v8i32
196   "llvm.intr.vector.reduce.or"(%arg2) : (!llvm.vec<8 x i32>) -> !llvm.i32
197   // CHECK: call i32 @llvm.vector.reduce.smax.v8i32
198   "llvm.intr.vector.reduce.smax"(%arg2) : (!llvm.vec<8 x i32>) -> !llvm.i32
199   // CHECK: call i32 @llvm.vector.reduce.smin.v8i32
200   "llvm.intr.vector.reduce.smin"(%arg2) : (!llvm.vec<8 x i32>) -> !llvm.i32
201   // CHECK: call i32 @llvm.vector.reduce.umax.v8i32
202   "llvm.intr.vector.reduce.umax"(%arg2) : (!llvm.vec<8 x i32>) -> !llvm.i32
203   // CHECK: call i32 @llvm.vector.reduce.umin.v8i32
204   "llvm.intr.vector.reduce.umin"(%arg2) : (!llvm.vec<8 x i32>) -> !llvm.i32
205   // CHECK: call float @llvm.vector.reduce.fadd.v8f32
206   "llvm.intr.vector.reduce.fadd"(%arg0, %arg1) : (!llvm.float, !llvm.vec<8 x float>) -> !llvm.float
207   // CHECK: call float @llvm.vector.reduce.fmul.v8f32
208   "llvm.intr.vector.reduce.fmul"(%arg0, %arg1) : (!llvm.float, !llvm.vec<8 x float>) -> !llvm.float
209   // CHECK: call reassoc float @llvm.vector.reduce.fadd.v8f32
210   "llvm.intr.vector.reduce.fadd"(%arg0, %arg1) {reassoc = true} : (!llvm.float, !llvm.vec<8 x float>) -> !llvm.float
211   // CHECK: call reassoc float @llvm.vector.reduce.fmul.v8f32
212   "llvm.intr.vector.reduce.fmul"(%arg0, %arg1) {reassoc = true} : (!llvm.float, !llvm.vec<8 x float>) -> !llvm.float
213   // CHECK: call i32 @llvm.vector.reduce.xor.v8i32
214   "llvm.intr.vector.reduce.xor"(%arg2) : (!llvm.vec<8 x i32>) -> !llvm.i32
215   llvm.return
216 }
217
218 // CHECK-LABEL: @matrix_intrinsics
219 //                                       4x16                       16x3
220 llvm.func @matrix_intrinsics(%A: !llvm.vec<64 x float>, %B: !llvm.vec<48 x float>,
221                              %ptr: !llvm.ptr<float>, %stride: !llvm.i64) {
222   // CHECK: call <12 x float> @llvm.matrix.multiply.v12f32.v64f32.v48f32(<64 x float> %0, <48 x float> %1, i32 4, i32 16, i32 3)
223   %C = llvm.intr.matrix.multiply %A, %B
224     { lhs_rows = 4: i32, lhs_columns = 16: i32 , rhs_columns = 3: i32} :
225     (!llvm.vec<64 x float>, !llvm.vec<48 x float>) -> !llvm.vec<12 x float>
226   // CHECK: call <48 x float> @llvm.matrix.transpose.v48f32(<48 x float> %1, i32 3, i32 16)
227   %D = llvm.intr.matrix.transpose %B { rows = 3: i32, columns = 16: i32} :
228     !llvm.vec<48 x float> into !llvm.vec<48 x float>
229   // CHECK: call <48 x float> @llvm.matrix.column.major.load.v48f32(float* align 4 %2, i64 %3, i1 false, i32 3, i32 16)
230   %E = llvm.intr.matrix.column.major.load %ptr, <stride=%stride>
231     { isVolatile = 0: i1, rows = 3: i32, columns = 16: i32} :
232     !llvm.vec<48 x float> from !llvm.ptr<float> stride !llvm.i64
233   // CHECK: call void @llvm.matrix.column.major.store.v48f32(<48 x float> %7, float* align 4 %2, i64 %3, i1 false, i32 3, i32 16)
234   llvm.intr.matrix.column.major.store %E, %ptr, <stride=%stride>
235     { isVolatile = 0: i1, rows = 3: i32, columns = 16: i32} :
236     !llvm.vec<48 x float> to !llvm.ptr<float> stride !llvm.i64
237   llvm.return
238 }
239
240 // CHECK-LABEL: @get_active_lane_mask
241 llvm.func @get_active_lane_mask(%base: !llvm.i64, %n: !llvm.i64) -> (!llvm.vec<7 x i1>) {
242   // CHECK: call <7 x i1> @llvm.get.active.lane.mask.v7i1.i64(i64 %0, i64 %1)
243   %0 = llvm.intr.get.active.lane.mask %base, %n : !llvm.i64, !llvm.i64 to !llvm.vec<7 x i1>
244   llvm.return %0 : !llvm.vec<7 x i1>
245 }
246
247 // CHECK-LABEL: @masked_load_store_intrinsics
248 llvm.func @masked_load_store_intrinsics(%A: !llvm.ptr<vec<7 x float>>, %mask: !llvm.vec<7 x i1>) {
249   // CHECK: call <7 x float> @llvm.masked.load.v7f32.p0v7f32(<7 x float>* %{{.*}}, i32 1, <7 x i1> %{{.*}}, <7 x float> undef)
250   %a = llvm.intr.masked.load %A, %mask { alignment = 1: i32} :
251     (!llvm.ptr<vec<7 x float>>, !llvm.vec<7 x i1>) -> !llvm.vec<7 x float>
252   // CHECK: call <7 x float> @llvm.masked.load.v7f32.p0v7f32(<7 x float>* %{{.*}}, i32 1, <7 x i1> %{{.*}}, <7 x float> %{{.*}})
253   %b = llvm.intr.masked.load %A, %mask, %a { alignment = 1: i32} :
254     (!llvm.ptr<vec<7 x float>>, !llvm.vec<7 x i1>, !llvm.vec<7 x float>) -> !llvm.vec<7 x float>
255   // CHECK: call void @llvm.masked.store.v7f32.p0v7f32(<7 x float> %{{.*}}, <7 x float>* %0, i32 {{.*}}, <7 x i1> %{{.*}})
256   llvm.intr.masked.store %b, %A, %mask { alignment = 1: i32} :
257     !llvm.vec<7 x float>, !llvm.vec<7 x i1> into !llvm.ptr<vec<7 x float>>
258   llvm.return
259 }
260
261 // CHECK-LABEL: @masked_gather_scatter_intrinsics
262 llvm.func @masked_gather_scatter_intrinsics(%M: !llvm.vec<7 x ptr<float>>, %mask: !llvm.vec<7 x i1>) {
263   // CHECK: call <7 x float> @llvm.masked.gather.v7f32.v7p0f32(<7 x float*> %{{.*}}, i32 1, <7 x i1> %{{.*}}, <7 x float> undef)
264   %a = llvm.intr.masked.gather %M, %mask { alignment = 1: i32} :
265       (!llvm.vec<7 x ptr<float>>, !llvm.vec<7 x i1>) -> !llvm.vec<7 x float>
266   // CHECK: call <7 x float> @llvm.masked.gather.v7f32.v7p0f32(<7 x float*> %{{.*}}, i32 1, <7 x i1> %{{.*}}, <7 x float> %{{.*}})
267   %b = llvm.intr.masked.gather %M, %mask, %a { alignment = 1: i32} :
268       (!llvm.vec<7 x ptr<float>>, !llvm.vec<7 x i1>, !llvm.vec<7 x float>) -> !llvm.vec<7 x float>
269   // CHECK: call void @llvm.masked.scatter.v7f32.v7p0f32(<7 x float> %{{.*}}, <7 x float*> %{{.*}}, i32 1, <7 x i1> %{{.*}})
270   llvm.intr.masked.scatter %b, %M, %mask { alignment = 1: i32} :
271       !llvm.vec<7 x float>, !llvm.vec<7 x i1> into !llvm.vec<7 x ptr<float>>
272   llvm.return
273 }
274
275 // CHECK-LABEL: @masked_expand_compress_intrinsics
276 llvm.func @masked_expand_compress_intrinsics(%ptr: !llvm.ptr<float>, %mask: !llvm.vec<7 x i1>, %passthru: !llvm.vec<7 x float>) {
277   // CHECK: call <7 x float> @llvm.masked.expandload.v7f32(float* %{{.*}}, <7 x i1> %{{.*}}, <7 x float> %{{.*}})
278   %0 = "llvm.intr.masked.expandload"(%ptr, %mask, %passthru)
279     : (!llvm.ptr<float>, !llvm.vec<7 x i1>, !llvm.vec<7 x float>) -> (!llvm.vec<7 x float>)
280   // CHECK: call void @llvm.masked.compressstore.v7f32(<7 x float> %{{.*}}, float* %{{.*}}, <7 x i1> %{{.*}})
281   "llvm.intr.masked.compressstore"(%0, %ptr, %mask)
282     : (!llvm.vec<7 x float>, !llvm.ptr<float>, !llvm.vec<7 x i1>) -> ()
283   llvm.return
284 }
285
286 // CHECK-LABEL: @memcpy_test
287 llvm.func @memcpy_test(%arg0: !llvm.i32, %arg1: !llvm.i1, %arg2: !llvm.ptr<i8>, %arg3: !llvm.ptr<i8>) {
288   // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 %{{.*}}, i1 %{{.*}})
289   "llvm.intr.memcpy"(%arg2, %arg3, %arg0, %arg1) : (!llvm.ptr<i8>, !llvm.ptr<i8>, !llvm.i32, !llvm.i1) -> ()
290   %sz = llvm.mlir.constant(10: i64) : !llvm.i64
291   // CHECK: call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 10, i1 %{{.*}})
292   "llvm.intr.memcpy.inline"(%arg2, %arg3, %sz, %arg1) : (!llvm.ptr<i8>, !llvm.ptr<i8>, !llvm.i64, !llvm.i1) -> ()
293   llvm.return
294 }
295
296 // CHECK-LABEL: @sadd_with_overflow_test
297 llvm.func @sadd_with_overflow_test(%arg0: !llvm.i32, %arg1: !llvm.i32, %arg2: !llvm.vec<8 x i32>, %arg3: !llvm.vec<8 x i32>) {
298   // CHECK: call { i32, i1 } @llvm.sadd.with.overflow.i32
299   "llvm.intr.sadd.with.overflow"(%arg0, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.struct<(i32, i1)>
300   // CHECK: call { <8 x i32>, <8 x i1> } @llvm.sadd.with.overflow.v8i32
301   "llvm.intr.sadd.with.overflow"(%arg2, %arg3) : (!llvm.vec<8 x i32>, !llvm.vec<8 x i32>) -> !llvm.struct<(vec<8 x i32>, vec<8 x i1>)>
302   llvm.return
303 }
304
305 // CHECK-LABEL: @uadd_with_overflow_test
306 llvm.func @uadd_with_overflow_test(%arg0: !llvm.i32, %arg1: !llvm.i32, %arg2: !llvm.vec<8 x i32>, %arg3: !llvm.vec<8 x i32>) {
307   // CHECK: call { i32, i1 } @llvm.uadd.with.overflow.i32
308   "llvm.intr.uadd.with.overflow"(%arg0, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.struct<(i32, i1)>
309   // CHECK: call { <8 x i32>, <8 x i1> } @llvm.uadd.with.overflow.v8i32
310   "llvm.intr.uadd.with.overflow"(%arg2, %arg3) : (!llvm.vec<8 x i32>, !llvm.vec<8 x i32>) -> !llvm.struct<(vec<8 x i32>, vec<8 x i1>)>
311   llvm.return
312 }
313
314 // CHECK-LABEL: @ssub_with_overflow_test
315 llvm.func @ssub_with_overflow_test(%arg0: !llvm.i32, %arg1: !llvm.i32, %arg2: !llvm.vec<8 x i32>, %arg3: !llvm.vec<8 x i32>) {
316   // CHECK: call { i32, i1 } @llvm.ssub.with.overflow.i32
317   "llvm.intr.ssub.with.overflow"(%arg0, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.struct<(i32, i1)>
318   // CHECK: call { <8 x i32>, <8 x i1> } @llvm.ssub.with.overflow.v8i32
319   "llvm.intr.ssub.with.overflow"(%arg2, %arg3) : (!llvm.vec<8 x i32>, !llvm.vec<8 x i32>) -> !llvm.struct<(vec<8 x i32>, vec<8 x i1>)>
320   llvm.return
321 }
322
323 // CHECK-LABEL: @usub_with_overflow_test
324 llvm.func @usub_with_overflow_test(%arg0: !llvm.i32, %arg1: !llvm.i32, %arg2: !llvm.vec<8 x i32>, %arg3: !llvm.vec<8 x i32>) {
325   // CHECK: call { i32, i1 } @llvm.usub.with.overflow.i32
326   "llvm.intr.usub.with.overflow"(%arg0, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.struct<(i32, i1)>
327   // CHECK: call { <8 x i32>, <8 x i1> } @llvm.usub.with.overflow.v8i32
328   "llvm.intr.usub.with.overflow"(%arg2, %arg3) : (!llvm.vec<8 x i32>, !llvm.vec<8 x i32>) -> !llvm.struct<(vec<8 x i32>, vec<8 x i1>)>
329   llvm.return
330 }
331
332 // CHECK-LABEL: @smul_with_overflow_test
333 llvm.func @smul_with_overflow_test(%arg0: !llvm.i32, %arg1: !llvm.i32, %arg2: !llvm.vec<8 x i32>, %arg3: !llvm.vec<8 x i32>) {
334   // CHECK: call { i32, i1 } @llvm.smul.with.overflow.i32
335   "llvm.intr.smul.with.overflow"(%arg0, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.struct<(i32, i1)>
336   // CHECK: call { <8 x i32>, <8 x i1> } @llvm.smul.with.overflow.v8i32
337   "llvm.intr.smul.with.overflow"(%arg2, %arg3) : (!llvm.vec<8 x i32>, !llvm.vec<8 x i32>) -> !llvm.struct<(vec<8 x i32>, vec<8 x i1>)>
338   llvm.return
339 }
340
341 // CHECK-LABEL: @umul_with_overflow_test
342 llvm.func @umul_with_overflow_test(%arg0: !llvm.i32, %arg1: !llvm.i32, %arg2: !llvm.vec<8 x i32>, %arg3: !llvm.vec<8 x i32>) {
343   // CHECK: call { i32, i1 } @llvm.umul.with.overflow.i32
344   "llvm.intr.umul.with.overflow"(%arg0, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.struct<(i32, i1)>
345   // CHECK: call { <8 x i32>, <8 x i1> } @llvm.umul.with.overflow.v8i32
346   "llvm.intr.umul.with.overflow"(%arg2, %arg3) : (!llvm.vec<8 x i32>, !llvm.vec<8 x i32>) -> !llvm.struct<(vec<8 x i32>, vec<8 x i1>)>
347   llvm.return
348 }
349
350 // Check that intrinsics are declared with appropriate types.
351 // CHECK-DAG: declare float @llvm.fma.f32(float, float, float)
352 // CHECK-DAG: declare <8 x float> @llvm.fma.v8f32(<8 x float>, <8 x float>, <8 x float>) #0
353 // CHECK-DAG: declare float @llvm.fmuladd.f32(float, float, float)
354 // CHECK-DAG: declare <8 x float> @llvm.fmuladd.v8f32(<8 x float>, <8 x float>, <8 x float>) #0
355 // CHECK-DAG: declare void @llvm.prefetch.p0i8(i8* nocapture readonly, i32 immarg, i32 immarg, i32)
356 // CHECK-DAG: declare float @llvm.exp.f32(float)
357 // CHECK-DAG: declare <8 x float> @llvm.exp.v8f32(<8 x float>) #0
358 // CHECK-DAG: declare float @llvm.log.f32(float)
359 // CHECK-DAG: declare <8 x float> @llvm.log.v8f32(<8 x float>) #0
360 // CHECK-DAG: declare float @llvm.log10.f32(float)
361 // CHECK-DAG: declare <8 x float> @llvm.log10.v8f32(<8 x float>) #0
362 // CHECK-DAG: declare float @llvm.log2.f32(float)
363 // CHECK-DAG: declare <8 x float> @llvm.log2.v8f32(<8 x float>) #0
364 // CHECK-DAG: declare float @llvm.fabs.f32(float)
365 // CHECK-DAG: declare <8 x float> @llvm.fabs.v8f32(<8 x float>) #0
366 // CHECK-DAG: declare float @llvm.sqrt.f32(float)
367 // CHECK-DAG: declare <8 x float> @llvm.sqrt.v8f32(<8 x float>) #0
368 // CHECK-DAG: declare float @llvm.ceil.f32(float)
369 // CHECK-DAG: declare <8 x float> @llvm.ceil.v8f32(<8 x float>) #0
370 // CHECK-DAG: declare float @llvm.cos.f32(float)
371 // CHECK-DAG: declare <8 x float> @llvm.cos.v8f32(<8 x float>) #0
372 // CHECK-DAG: declare float @llvm.copysign.f32(float, float)
373 // CHECK-DAG: declare <12 x float> @llvm.matrix.multiply.v12f32.v64f32.v48f32(<64 x float>, <48 x float>, i32 immarg, i32 immarg, i32 immarg)
374 // CHECK-DAG: declare <48 x float> @llvm.matrix.transpose.v48f32(<48 x float>, i32 immarg, i32 immarg)
375 // CHECK-DAG: declare <48 x float> @llvm.matrix.column.major.load.v48f32(float* nocapture, i64, i1 immarg, i32 immarg, i32 immarg)
376 // CHECK-DAG: declare void @llvm.matrix.column.major.store.v48f32(<48 x float>, float* nocapture writeonly, i64, i1 immarg, i32 immarg, i32 immarg)
377 // CHECK-DAG: declare <7 x i1> @llvm.get.active.lane.mask.v7i1.i64(i64, i64)
378 // CHECK-DAG: declare <7 x float> @llvm.masked.load.v7f32.p0v7f32(<7 x float>*, i32 immarg, <7 x i1>, <7 x float>)
379 // CHECK-DAG: declare void @llvm.masked.store.v7f32.p0v7f32(<7 x float>, <7 x float>*, i32 immarg, <7 x i1>)
380 // CHECK-DAG: declare <7 x float> @llvm.masked.gather.v7f32.v7p0f32(<7 x float*>, i32 immarg, <7 x i1>, <7 x float>)
381 // CHECK-DAG: declare void @llvm.masked.scatter.v7f32.v7p0f32(<7 x float>, <7 x float*>, i32 immarg, <7 x i1>)
382 // CHECK-DAG: declare <7 x float> @llvm.masked.expandload.v7f32(float*, <7 x i1>, <7 x float>)
383 // CHECK-DAG: declare void @llvm.masked.compressstore.v7f32(<7 x float>, float*, <7 x i1>)
384 // CHECK-DAG: declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i32, i1 immarg)
385 // CHECK-DAG: declare void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64 immarg, i1 immarg)
386 // CHECK-DAG: declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
387 // CHECK-DAG: declare { <8 x i32>, <8 x i1> } @llvm.sadd.with.overflow.v8i32(<8 x i32>, <8 x i32>) #0
388 // CHECK-DAG: declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
389 // CHECK-DAG: declare { <8 x i32>, <8 x i1> } @llvm.uadd.with.overflow.v8i32(<8 x i32>, <8 x i32>) #0
390 // CHECK-DAG: declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
391 // CHECK-DAG: declare { <8 x i32>, <8 x i1> } @llvm.ssub.with.overflow.v8i32(<8 x i32>, <8 x i32>) #0
392 // CHECK-DAG: declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
393 // CHECK-DAG: declare { <8 x i32>, <8 x i1> } @llvm.usub.with.overflow.v8i32(<8 x i32>, <8 x i32>) #0
394 // CHECK-DAG: declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
395 // CHECK-DAG: declare { <8 x i32>, <8 x i1> } @llvm.umul.with.overflow.v8i32(<8 x i32>, <8 x i32>) #0