1 // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
2 // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
3 // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
4 // RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF
5 // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
6 // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
7 // RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF
9 // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
10 // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
11 // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
12 // RUN: --check-prefixes=CHECK,NATIVE_HALF,SPIR_NATIVE_HALF,SPIR_CHECK
13 // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
14 // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
15 // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF,SPIR_CHECK
17 #ifdef __HLSL_ENABLE_16_BIT
18 // DXIL_NATIVE_HALF: %dx.umad = call i16 @llvm.dx.umad.i16(i16 %0, i16 %1, i16 %2)
19 // DXIL_NATIVE_HALF: ret i16 %dx.umad
20 // SPIR_NATIVE_HALF: mul nuw i16 %{{.*}}, %{{.*}}
21 // SPIR_NATIVE_HALF: add nuw i16 %{{.*}}, %{{.*}}
22 uint16_t test_mad_uint16_t(uint16_t p0, uint16_t p1, uint16_t p2) { return mad(p0, p1, p2); }
24 // DXIL_NATIVE_HALF: %dx.umad = call <2 x i16> @llvm.dx.umad.v2i16(<2 x i16> %0, <2 x i16> %1, <2 x i16> %2)
25 // DXIL_NATIVE_HALF: ret <2 x i16> %dx.umad
26 // SPIR_NATIVE_HALF: mul nuw <2 x i16> %{{.*}}, %{{.*}}
27 // SPIR_NATIVE_HALF: add nuw <2 x i16> %{{.*}}, %{{.*}}
28 uint16_t2 test_mad_uint16_t2(uint16_t2 p0, uint16_t2 p1, uint16_t2 p2) { return mad(p0, p1, p2); }
30 // DXIL_NATIVE_HALF: %dx.umad = call <3 x i16> @llvm.dx.umad.v3i16(<3 x i16> %0, <3 x i16> %1, <3 x i16> %2)
31 // DXIL_NATIVE_HALF: ret <3 x i16> %dx.umad
32 // SPIR_NATIVE_HALF: mul nuw <3 x i16> %{{.*}}, %{{.*}}
33 // SPIR_NATIVE_HALF: add nuw <3 x i16> %{{.*}}, %{{.*}}
34 uint16_t3 test_mad_uint16_t3(uint16_t3 p0, uint16_t3 p1, uint16_t3 p2) { return mad(p0, p1, p2); }
36 // DXIL_NATIVE_HALF: %dx.umad = call <4 x i16> @llvm.dx.umad.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2)
37 // DXIL_NATIVE_HALF: ret <4 x i16> %dx.umad
38 // SPIR_NATIVE_HALF: mul nuw <4 x i16> %{{.*}}, %{{.*}}
39 // SPIR_NATIVE_HALF: add nuw <4 x i16> %{{.*}}, %{{.*}}
40 uint16_t4 test_mad_uint16_t4(uint16_t4 p0, uint16_t4 p1, uint16_t4 p2) { return mad(p0, p1, p2); }
42 // DXIL_NATIVE_HALF: %dx.imad = call i16 @llvm.dx.imad.i16(i16 %0, i16 %1, i16 %2)
43 // DXIL_NATIVE_HALF: ret i16 %dx.imad
44 // SPIR_NATIVE_HALF: mul nsw i16 %{{.*}}, %{{.*}}
45 // SPIR_NATIVE_HALF: add nsw i16 %{{.*}}, %{{.*}}
46 int16_t test_mad_int16_t(int16_t p0, int16_t p1, int16_t p2) { return mad(p0, p1, p2); }
48 // DXIL_NATIVE_HALF: %dx.imad = call <2 x i16> @llvm.dx.imad.v2i16(<2 x i16> %0, <2 x i16> %1, <2 x i16> %2)
49 // DXIL_NATIVE_HALF: ret <2 x i16> %dx.imad
50 // SPIR_NATIVE_HALF: mul nsw <2 x i16> %{{.*}}, %{{.*}}
51 // SPIR_NATIVE_HALF: add nsw <2 x i16> %{{.*}}, %{{.*}}
52 int16_t2 test_mad_int16_t2(int16_t2 p0, int16_t2 p1, int16_t2 p2) { return mad(p0, p1, p2); }
54 // DXIL_NATIVE_HALF: %dx.imad = call <3 x i16> @llvm.dx.imad.v3i16(<3 x i16> %0, <3 x i16> %1, <3 x i16> %2)
55 // DXIL_NATIVE_HALF: ret <3 x i16> %dx.imad
56 // SPIR_NATIVE_HALF: mul nsw <3 x i16> %{{.*}}, %{{.*}}
57 // SPIR_NATIVE_HALF: add nsw <3 x i16> %{{.*}}, %{{.*}}
58 int16_t3 test_mad_int16_t3(int16_t3 p0, int16_t3 p1, int16_t3 p2) { return mad(p0, p1, p2); }
60 // DXIL_NATIVE_HALF: %dx.imad = call <4 x i16> @llvm.dx.imad.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2)
61 // DXIL_NATIVE_HALF: ret <4 x i16> %dx.imad
62 // SPIR_NATIVE_HALF: mul nsw <4 x i16> %{{.*}}, %{{.*}}
63 // SPIR_NATIVE_HALF: add nsw <4 x i16> %{{.*}}, %{{.*}}
64 int16_t4 test_mad_int16_t4(int16_t4 p0, int16_t4 p1, int16_t4 p2) { return mad(p0, p1, p2); }
65 #endif // __HLSL_ENABLE_16_BIT
67 // NATIVE_HALF: %[[p0:.*]] = load half, ptr %p0.addr, align 2
68 // NATIVE_HALF: %[[p1:.*]] = load half, ptr %p1.addr, align 2
69 // NATIVE_HALF: %[[p2:.*]] = load half, ptr %p2.addr, align 2
70 // NATIVE_HALF: %hlsl.fmad = call half @llvm.fmuladd.f16(half %[[p0]], half %[[p1]], half %[[p2]])
71 // NATIVE_HALF: ret half %hlsl.fmad
72 // NO_HALF: %[[p0:.*]] = load float, ptr %p0.addr, align 4
73 // NO_HALF: %[[p1:.*]] = load float, ptr %p1.addr, align 4
74 // NO_HALF: %[[p2:.*]] = load float, ptr %p2.addr, align 4
75 // NO_HALF: %hlsl.fmad = call float @llvm.fmuladd.f32(float %[[p0]], float %[[p1]], float %[[p2]])
76 // NO_HALF: ret float %hlsl.fmad
77 half test_mad_half(half p0, half p1, half p2) { return mad(p0, p1, p2); }
79 // NATIVE_HALF: %[[p0:.*]] = load <2 x half>, ptr %p0.addr, align 4
80 // NATIVE_HALF: %[[p1:.*]] = load <2 x half>, ptr %p1.addr, align 4
81 // NATIVE_HALF: %[[p2:.*]] = load <2 x half>, ptr %p2.addr, align 4
82 // NATIVE_HALF: %hlsl.fmad = call <2 x half> @llvm.fmuladd.v2f16(<2 x half> %[[p0]], <2 x half> %[[p1]], <2 x half> %[[p2]])
83 // NATIVE_HALF: ret <2 x half> %hlsl.fmad
84 // NO_HALF: %[[p0:.*]] = load <2 x float>, ptr %p0.addr, align 8
85 // NO_HALF: %[[p1:.*]] = load <2 x float>, ptr %p1.addr, align 8
86 // NO_HALF: %[[p2:.*]] = load <2 x float>, ptr %p2.addr, align 8
87 // NO_HALF: %hlsl.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %[[p0]], <2 x float> %[[p1]], <2 x float> %[[p2]])
88 // NO_HALF: ret <2 x float> %hlsl.fmad
89 half2 test_mad_half2(half2 p0, half2 p1, half2 p2) { return mad(p0, p1, p2); }
91 // NATIVE_HALF: %[[p0:.*]] = load <3 x half>, ptr %p0.addr, align 8
92 // NATIVE_HALF: %[[p1:.*]] = load <3 x half>, ptr %p1.addr, align 8
93 // NATIVE_HALF: %[[p2:.*]] = load <3 x half>, ptr %p2.addr, align 8
94 // NATIVE_HALF: %hlsl.fmad = call <3 x half> @llvm.fmuladd.v3f16(<3 x half> %[[p0]], <3 x half> %[[p1]], <3 x half> %[[p2]])
95 // NATIVE_HALF: ret <3 x half> %hlsl.fmad
96 // NO_HALF: %[[p0:.*]] = load <3 x float>, ptr %p0.addr, align 16
97 // NO_HALF: %[[p1:.*]] = load <3 x float>, ptr %p1.addr, align 16
98 // NO_HALF: %[[p2:.*]] = load <3 x float>, ptr %p2.addr, align 16
99 // NO_HALF: %hlsl.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %[[p0]], <3 x float> %[[p1]], <3 x float> %[[p2]])
100 // NO_HALF: ret <3 x float> %hlsl.fmad
101 half3 test_mad_half3(half3 p0, half3 p1, half3 p2) { return mad(p0, p1, p2); }
103 // NATIVE_HALF: %[[p0:.*]] = load <4 x half>, ptr %p0.addr, align 8
104 // NATIVE_HALF: %[[p1:.*]] = load <4 x half>, ptr %p1.addr, align 8
105 // NATIVE_HALF: %[[p2:.*]] = load <4 x half>, ptr %p2.addr, align 8
106 // NATIVE_HALF: %hlsl.fmad = call <4 x half> @llvm.fmuladd.v4f16(<4 x half> %[[p0]], <4 x half> %[[p1]], <4 x half> %[[p2]])
107 // NATIVE_HALF: ret <4 x half> %hlsl.fmad
108 // NO_HALF: %[[p0:.*]] = load <4 x float>, ptr %p0.addr, align 16
109 // NO_HALF: %[[p1:.*]] = load <4 x float>, ptr %p1.addr, align 16
110 // NO_HALF: %[[p2:.*]] = load <4 x float>, ptr %p2.addr, align 16
111 // NO_HALF: %hlsl.fmad = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %[[p0]], <4 x float> %[[p1]], <4 x float> %[[p2]])
112 // NO_HALF: ret <4 x float> %hlsl.fmad
113 half4 test_mad_half4(half4 p0, half4 p1, half4 p2) { return mad(p0, p1, p2); }
115 // CHECK: %[[p0:.*]] = load float, ptr %p0.addr, align 4
116 // CHECK: %[[p1:.*]] = load float, ptr %p1.addr, align 4
117 // CHECK: %[[p2:.*]] = load float, ptr %p2.addr, align 4
118 // CHECK: %hlsl.fmad = call float @llvm.fmuladd.f32(float %[[p0]], float %[[p1]], float %[[p2]])
119 // CHECK: ret float %hlsl.fmad
120 float test_mad_float(float p0, float p1, float p2) { return mad(p0, p1, p2); }
122 // CHECK: %[[p0:.*]] = load <2 x float>, ptr %p0.addr, align 8
123 // CHECK: %[[p1:.*]] = load <2 x float>, ptr %p1.addr, align 8
124 // CHECK: %[[p2:.*]] = load <2 x float>, ptr %p2.addr, align 8
125 // CHECK: %hlsl.fmad = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %[[p0]], <2 x float> %[[p1]], <2 x float> %[[p2]])
126 // CHECK: ret <2 x float> %hlsl.fmad
127 float2 test_mad_float2(float2 p0, float2 p1, float2 p2) { return mad(p0, p1, p2); }
129 // CHECK: %[[p0:.*]] = load <3 x float>, ptr %p0.addr, align 16
130 // CHECK: %[[p1:.*]] = load <3 x float>, ptr %p1.addr, align 16
131 // CHECK: %[[p2:.*]] = load <3 x float>, ptr %p2.addr, align 16
132 // CHECK: %hlsl.fmad = call <3 x float> @llvm.fmuladd.v3f32(<3 x float> %[[p0]], <3 x float> %[[p1]], <3 x float> %[[p2]])
133 // CHECK: ret <3 x float> %hlsl.fmad
134 float3 test_mad_float3(float3 p0, float3 p1, float3 p2) { return mad(p0, p1, p2); }
136 // CHECK: %[[p0:.*]] = load <4 x float>, ptr %p0.addr, align 16
137 // CHECK: %[[p1:.*]] = load <4 x float>, ptr %p1.addr, align 16
138 // CHECK: %[[p2:.*]] = load <4 x float>, ptr %p2.addr, align 16
139 // CHECK: %hlsl.fmad = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %[[p0]], <4 x float> %[[p1]], <4 x float> %[[p2]])
140 // CHECK: ret <4 x float> %hlsl.fmad
141 float4 test_mad_float4(float4 p0, float4 p1, float4 p2) { return mad(p0, p1, p2); }
143 // CHECK: %[[p0:.*]] = load double, ptr %p0.addr, align 8
144 // CHECK: %[[p1:.*]] = load double, ptr %p1.addr, align 8
145 // CHECK: %[[p2:.*]] = load double, ptr %p2.addr, align 8
146 // CHECK: %hlsl.fmad = call double @llvm.fmuladd.f64(double %[[p0]], double %[[p1]], double %[[p2]])
147 // CHECK: ret double %hlsl.fmad
148 double test_mad_double(double p0, double p1, double p2) { return mad(p0, p1, p2); }
150 // CHECK: %[[p0:.*]] = load <2 x double>, ptr %p0.addr, align 16
151 // CHECK: %[[p1:.*]] = load <2 x double>, ptr %p1.addr, align 16
152 // CHECK: %[[p2:.*]] = load <2 x double>, ptr %p2.addr, align 16
153 // CHECK: %hlsl.fmad = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %[[p0]], <2 x double> %[[p1]], <2 x double> %[[p2]])
154 // CHECK: ret <2 x double> %hlsl.fmad
155 double2 test_mad_double2(double2 p0, double2 p1, double2 p2) { return mad(p0, p1, p2); }
157 // CHECK: %[[p0:.*]] = load <3 x double>, ptr %p0.addr, align 32
158 // CHECK: %[[p1:.*]] = load <3 x double>, ptr %p1.addr, align 32
159 // CHECK: %[[p2:.*]] = load <3 x double>, ptr %p2.addr, align 32
160 // CHECK: %hlsl.fmad = call <3 x double> @llvm.fmuladd.v3f64(<3 x double> %[[p0]], <3 x double> %[[p1]], <3 x double> %[[p2]])
161 // CHECK: ret <3 x double> %hlsl.fmad
162 double3 test_mad_double3(double3 p0, double3 p1, double3 p2) { return mad(p0, p1, p2); }
164 // CHECK: %[[p0:.*]] = load <4 x double>, ptr %p0.addr, align 32
165 // CHECK: %[[p1:.*]] = load <4 x double>, ptr %p1.addr, align 32
166 // CHECK: %[[p2:.*]] = load <4 x double>, ptr %p2.addr, align 32
167 // CHECK: %hlsl.fmad = call <4 x double> @llvm.fmuladd.v4f64(<4 x double> %[[p0]], <4 x double> %[[p1]], <4 x double> %[[p2]])
168 // CHECK: ret <4 x double> %hlsl.fmad
169 double4 test_mad_double4(double4 p0, double4 p1, double4 p2) { return mad(p0, p1, p2); }
171 // DXIL_CHECK: %dx.imad = call i32 @llvm.dx.imad.i32(i32 %0, i32 %1, i32 %2)
172 // DXIL_CHECK: ret i32 %dx.imad
173 // SPIR_CHECK: mul nsw i32 %{{.*}}, %{{.*}}
174 // SPIR_CHECK: add nsw i32 %{{.*}}, %{{.*}}
175 int test_mad_int(int p0, int p1, int p2) { return mad(p0, p1, p2); }
177 // DXIL_CHECK: %dx.imad = call <2 x i32> @llvm.dx.imad.v2i32(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2)
178 // DXIL_CHECK: ret <2 x i32> %dx.imad
179 // SPIR_CHECK: mul nsw <2 x i32> %{{.*}}, %{{.*}}
180 // SPIR_CHECK: add nsw <2 x i32> %{{.*}}, %{{.*}}
181 int2 test_mad_int2(int2 p0, int2 p1, int2 p2) { return mad(p0, p1, p2); }
183 // DXIL_CHECK: %dx.imad = call <3 x i32> @llvm.dx.imad.v3i32(<3 x i32> %0, <3 x i32> %1, <3 x i32> %2)
184 // DXIL_CHECK: ret <3 x i32> %dx.imad
185 // SPIR_CHECK: mul nsw <3 x i32> %{{.*}}, %{{.*}}
186 // SPIR_CHECK: add nsw <3 x i32> %{{.*}}, %{{.*}}
187 int3 test_mad_int3(int3 p0, int3 p1, int3 p2) { return mad(p0, p1, p2); }
189 // DXIL_CHECK: %dx.imad = call <4 x i32> @llvm.dx.imad.v4i32(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2)
190 // DXIL_CHECK: ret <4 x i32> %dx.imad
191 // SPIR_CHECK: mul nsw <4 x i32> %{{.*}}, %{{.*}}
192 // SPIR_CHECK: add nsw <4 x i32> %{{.*}}, %{{.*}}
193 int4 test_mad_int4(int4 p0, int4 p1, int4 p2) { return mad(p0, p1, p2); }
195 // DXIL_CHECK: %dx.imad = call i64 @llvm.dx.imad.i64(i64 %0, i64 %1, i64 %2)
196 // DXIL_CHECK: ret i64 %dx.imad
197 // SPIR_CHECK: mul nsw i64 %{{.*}}, %{{.*}}
198 // SPIR_CHECK: add nsw i64 %{{.*}}, %{{.*}}
199 int64_t test_mad_int64_t(int64_t p0, int64_t p1, int64_t p2) { return mad(p0, p1, p2); }
201 // DXIL_CHECK: %dx.imad = call <2 x i64> @llvm.dx.imad.v2i64(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2)
202 // DXIL_CHECK: ret <2 x i64> %dx.imad
203 // SPIR_CHECK: mul nsw <2 x i64> %{{.*}}, %{{.*}}
204 // SPIR_CHECK: add nsw <2 x i64> %{{.*}}, %{{.*}}
205 int64_t2 test_mad_int64_t2(int64_t2 p0, int64_t2 p1, int64_t2 p2) { return mad(p0, p1, p2); }
207 // DXIL_CHECK: %dx.imad = call <3 x i64> @llvm.dx.imad.v3i64(<3 x i64> %0, <3 x i64> %1, <3 x i64> %2)
208 // DXIL_CHECK: ret <3 x i64> %dx.imad
209 // SPIR_CHECK: mul nsw <3 x i64> %{{.*}}, %{{.*}}
210 // SPIR_CHECK: add nsw <3 x i64> %{{.*}}, %{{.*}}
211 int64_t3 test_mad_int64_t3(int64_t3 p0, int64_t3 p1, int64_t3 p2) { return mad(p0, p1, p2); }
213 // DXIL_CHECK: %dx.imad = call <4 x i64> @llvm.dx.imad.v4i64(<4 x i64> %0, <4 x i64> %1, <4 x i64> %2)
214 // DXIL_CHECK: ret <4 x i64> %dx.imad
215 // SPIR_CHECK: mul nsw <4 x i64> %{{.*}}, %{{.*}}
216 // SPIR_CHECK: add nsw <4 x i64> %{{.*}}, %{{.*}}
217 int64_t4 test_mad_int64_t4(int64_t4 p0, int64_t4 p1, int64_t4 p2) { return mad(p0, p1, p2); }
219 // DXIL_CHECK: %dx.umad = call i32 @llvm.dx.umad.i32(i32 %0, i32 %1, i32 %2)
220 // DXIL_CHECK: ret i32 %dx.umad
221 // SPIR_CHECK: mul nuw i32 %{{.*}}, %{{.*}}
222 // SPIR_CHECK: add nuw i32 %{{.*}}, %{{.*}}
223 uint test_mad_uint(uint p0, uint p1, uint p2) { return mad(p0, p1, p2); }
225 // DXIL_CHECK: %dx.umad = call <2 x i32> @llvm.dx.umad.v2i32(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2)
226 // DXIL_CHECK: ret <2 x i32> %dx.umad
227 // SPIR_CHECK: mul nuw <2 x i32> %{{.*}}, %{{.*}}
228 // SPIR_CHECK: add nuw <2 x i32> %{{.*}}, %{{.*}}
229 uint2 test_mad_uint2(uint2 p0, uint2 p1, uint2 p2) { return mad(p0, p1, p2); }
231 // DXIL_CHECK: %dx.umad = call <3 x i32> @llvm.dx.umad.v3i32(<3 x i32> %0, <3 x i32> %1, <3 x i32> %2)
232 // DXIL_CHECK: ret <3 x i32> %dx.umad
233 // SPIR_CHECK: mul nuw <3 x i32> %{{.*}}, %{{.*}}
234 // SPIR_CHECK: add nuw <3 x i32> %{{.*}}, %{{.*}}
235 uint3 test_mad_uint3(uint3 p0, uint3 p1, uint3 p2) { return mad(p0, p1, p2); }
237 // DXIL_CHECK: %dx.umad = call <4 x i32> @llvm.dx.umad.v4i32(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2)
238 // DXIL_CHECK: ret <4 x i32> %dx.umad
239 // SPIR_CHECK: mul nuw <4 x i32> %{{.*}}, %{{.*}}
240 // SPIR_CHECK: add nuw <4 x i32> %{{.*}}, %{{.*}}
241 uint4 test_mad_uint4(uint4 p0, uint4 p1, uint4 p2) { return mad(p0, p1, p2); }
243 // DXIL_CHECK: %dx.umad = call i64 @llvm.dx.umad.i64(i64 %0, i64 %1, i64 %2)
244 // DXIL_CHECK: ret i64 %dx.umad
245 // SPIR_CHECK: mul nuw i64 %{{.*}}, %{{.*}}
246 // SPIR_CHECK: add nuw i64 %{{.*}}, %{{.*}}
247 uint64_t test_mad_uint64_t(uint64_t p0, uint64_t p1, uint64_t p2) { return mad(p0, p1, p2); }
249 // DXIL_CHECK: %dx.umad = call <2 x i64> @llvm.dx.umad.v2i64(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2)
250 // DXIL_CHECK: ret <2 x i64> %dx.umad
251 // SPIR_CHECK: mul nuw <2 x i64> %{{.*}}, %{{.*}}
252 // SPIR_CHECK: add nuw <2 x i64> %{{.*}}, %{{.*}}
253 uint64_t2 test_mad_uint64_t2(uint64_t2 p0, uint64_t2 p1, uint64_t2 p2) { return mad(p0, p1, p2); }
255 // DXIL_CHECK: %dx.umad = call <3 x i64> @llvm.dx.umad.v3i64(<3 x i64> %0, <3 x i64> %1, <3 x i64> %2)
256 // DXIL_CHECK: ret <3 x i64> %dx.umad
257 // SPIR_CHECK: mul nuw <3 x i64> %{{.*}}, %{{.*}}
258 // SPIR_CHECK: add nuw <3 x i64> %{{.*}}, %{{.*}}
259 uint64_t3 test_mad_uint64_t3(uint64_t3 p0, uint64_t3 p1, uint64_t3 p2) { return mad(p0, p1, p2); }
261 // DXIL_CHECK: %dx.umad = call <4 x i64> @llvm.dx.umad.v4i64(<4 x i64> %0, <4 x i64> %1, <4 x i64> %2)
262 // DXIL_CHECK: ret <4 x i64> %dx.umad
263 // SPIR_CHECK: mul nuw <4 x i64> %{{.*}}, %{{.*}}
264 // SPIR_CHECK: add nuw <4 x i64> %{{.*}}, %{{.*}}
265 uint64_t4 test_mad_uint64_t4(uint64_t4 p0, uint64_t4 p1, uint64_t4 p2) { return mad(p0, p1, p2); }