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,DXCHECK,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,DXCHECK,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,SPVCHECK,NATIVE_HALF
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,SPVCHECK,NO_HALF
18 // CHECK: %hlsl.dot = mul i32
19 // CHECK: ret i32 %hlsl.dot
20 int test_dot_int(int p0, int p1) { return dot(p0, p1); }
22 // Capture the expected interchange format so not every check needs to be duplicated
23 // DXCHECK: %hlsl.dot = call i32 @llvm.[[ICF:dx]].sdot.v2i32(<2 x i32>
24 // SPVCHECK: %hlsl.dot = call i32 @llvm.[[ICF:spv]].sdot.v2i32(<2 x i32>
25 // CHECK: ret i32 %hlsl.dot
26 int test_dot_int2(int2 p0, int2 p1) { return dot(p0, p1); }
28 // CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].sdot.v3i32(<3 x i32>
29 // CHECK: ret i32 %hlsl.dot
30 int test_dot_int3(int3 p0, int3 p1) { return dot(p0, p1); }
32 // CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].sdot.v4i32(<4 x i32>
33 // CHECK: ret i32 %hlsl.dot
34 int test_dot_int4(int4 p0, int4 p1) { return dot(p0, p1); }
36 // CHECK: %hlsl.dot = mul i32
37 // CHECK: ret i32 %hlsl.dot
38 uint test_dot_uint(uint p0, uint p1) { return dot(p0, p1); }
40 // CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].udot.v2i32(<2 x i32>
41 // CHECK: ret i32 %hlsl.dot
42 uint test_dot_uint2(uint2 p0, uint2 p1) { return dot(p0, p1); }
44 // CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].udot.v3i32(<3 x i32>
45 // CHECK: ret i32 %hlsl.dot
46 uint test_dot_uint3(uint3 p0, uint3 p1) { return dot(p0, p1); }
48 // CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].udot.v4i32(<4 x i32>
49 // CHECK: ret i32 %hlsl.dot
50 uint test_dot_uint4(uint4 p0, uint4 p1) { return dot(p0, p1); }
52 // CHECK: %hlsl.dot = mul i64
53 // CHECK: ret i64 %hlsl.dot
54 int64_t test_dot_long(int64_t p0, int64_t p1) { return dot(p0, p1); }
56 // CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].sdot.v2i64(<2 x i64>
57 // CHECK: ret i64 %hlsl.dot
58 int64_t test_dot_long2(int64_t2 p0, int64_t2 p1) { return dot(p0, p1); }
60 // CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].sdot.v3i64(<3 x i64>
61 // CHECK: ret i64 %hlsl.dot
62 int64_t test_dot_long3(int64_t3 p0, int64_t3 p1) { return dot(p0, p1); }
64 // CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].sdot.v4i64(<4 x i64>
65 // CHECK: ret i64 %hlsl.dot
66 int64_t test_dot_long4(int64_t4 p0, int64_t4 p1) { return dot(p0, p1); }
68 // CHECK: %hlsl.dot = mul i64
69 // CHECK: ret i64 %hlsl.dot
70 uint64_t test_dot_ulong(uint64_t p0, uint64_t p1) { return dot(p0, p1); }
72 // CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].udot.v2i64(<2 x i64>
73 // CHECK: ret i64 %hlsl.dot
74 uint64_t test_dot_ulong2(uint64_t2 p0, uint64_t2 p1) { return dot(p0, p1); }
76 // CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].udot.v3i64(<3 x i64>
77 // CHECK: ret i64 %hlsl.dot
78 uint64_t test_dot_ulong3(uint64_t3 p0, uint64_t3 p1) { return dot(p0, p1); }
80 // CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].udot.v4i64(<4 x i64>
81 // CHECK: ret i64 %hlsl.dot
82 uint64_t test_dot_ulong4(uint64_t4 p0, uint64_t4 p1) { return dot(p0, p1); }
84 #ifdef __HLSL_ENABLE_16_BIT
85 // NATIVE_HALF: %hlsl.dot = mul i16
86 // NATIVE_HALF: ret i16 %hlsl.dot
87 int16_t test_dot_short(int16_t p0, int16_t p1) { return dot(p0, p1); }
89 // NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].sdot.v2i16(<2 x i16>
90 // NATIVE_HALF: ret i16 %hlsl.dot
91 int16_t test_dot_short2(int16_t2 p0, int16_t2 p1) { return dot(p0, p1); }
93 // NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].sdot.v3i16(<3 x i16>
94 // NATIVE_HALF: ret i16 %hlsl.dot
95 int16_t test_dot_short3(int16_t3 p0, int16_t3 p1) { return dot(p0, p1); }
97 // NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].sdot.v4i16(<4 x i16>
98 // NATIVE_HALF: ret i16 %hlsl.dot
99 int16_t test_dot_short4(int16_t4 p0, int16_t4 p1) { return dot(p0, p1); }
101 // NATIVE_HALF: %hlsl.dot = mul i16
102 // NATIVE_HALF: ret i16 %hlsl.dot
103 uint16_t test_dot_ushort(uint16_t p0, uint16_t p1) { return dot(p0, p1); }
105 // NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].udot.v2i16(<2 x i16>
106 // NATIVE_HALF: ret i16 %hlsl.dot
107 uint16_t test_dot_ushort2(uint16_t2 p0, uint16_t2 p1) { return dot(p0, p1); }
109 // NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].udot.v3i16(<3 x i16>
110 // NATIVE_HALF: ret i16 %hlsl.dot
111 uint16_t test_dot_ushort3(uint16_t3 p0, uint16_t3 p1) { return dot(p0, p1); }
113 // NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].udot.v4i16(<4 x i16>
114 // NATIVE_HALF: ret i16 %hlsl.dot
115 uint16_t test_dot_ushort4(uint16_t4 p0, uint16_t4 p1) { return dot(p0, p1); }
118 // NATIVE_HALF: %hlsl.dot = fmul half
119 // NATIVE_HALF: ret half %hlsl.dot
120 // NO_HALF: %hlsl.dot = fmul float
121 // NO_HALF: ret float %hlsl.dot
122 half test_dot_half(half p0, half p1) { return dot(p0, p1); }
124 // NATIVE_HALF: %hlsl.dot = call half @llvm.[[ICF]].fdot.v2f16(<2 x half>
125 // NATIVE_HALF: ret half %hlsl.dot
126 // NO_HALF: %hlsl.dot = call float @llvm.[[ICF]].fdot.v2f32(<2 x float>
127 // NO_HALF: ret float %hlsl.dot
128 half test_dot_half2(half2 p0, half2 p1) { return dot(p0, p1); }
130 // NATIVE_HALF: %hlsl.dot = call half @llvm.[[ICF]].fdot.v3f16(<3 x half>
131 // NATIVE_HALF: ret half %hlsl.dot
132 // NO_HALF: %hlsl.dot = call float @llvm.[[ICF]].fdot.v3f32(<3 x float>
133 // NO_HALF: ret float %hlsl.dot
134 half test_dot_half3(half3 p0, half3 p1) { return dot(p0, p1); }
136 // NATIVE_HALF: %hlsl.dot = call half @llvm.[[ICF]].fdot.v4f16(<4 x half>
137 // NATIVE_HALF: ret half %hlsl.dot
138 // NO_HALF: %hlsl.dot = call float @llvm.[[ICF]].fdot.v4f32(<4 x float>
139 // NO_HALF: ret float %hlsl.dot
140 half test_dot_half4(half4 p0, half4 p1) { return dot(p0, p1); }
142 // CHECK: %hlsl.dot = fmul float
143 // CHECK: ret float %hlsl.dot
144 float test_dot_float(float p0, float p1) { return dot(p0, p1); }
146 // CHECK: %hlsl.dot = call float @llvm.[[ICF]].fdot.v2f32(<2 x float>
147 // CHECK: ret float %hlsl.dot
148 float test_dot_float2(float2 p0, float2 p1) { return dot(p0, p1); }
150 // CHECK: %hlsl.dot = call float @llvm.[[ICF]].fdot.v3f32(<3 x float>
151 // CHECK: ret float %hlsl.dot
152 float test_dot_float3(float3 p0, float3 p1) { return dot(p0, p1); }
154 // CHECK: %hlsl.dot = call float @llvm.[[ICF]].fdot.v4f32(<4 x float>
155 // CHECK: ret float %hlsl.dot
156 float test_dot_float4(float4 p0, float4 p1) { return dot(p0, p1); }
158 // CHECK: %hlsl.dot = fmul double
159 // CHECK: ret double %hlsl.dot
160 double test_dot_double(double p0, double p1) { return dot(p0, p1); }