xref: /llvm-project/clang/test/CodeGenHLSL/builtins/dot.hlsl (revision 762f1b17b2815ccdfb4e5cb5412cb6210db92f73)
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
8
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
16
17
18// CHECK: %hlsl.dot = mul i32
19// CHECK: ret i32 %hlsl.dot
20int test_dot_int(int p0, int p1) { return dot(p0, p1); }
21
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
26int test_dot_int2(int2 p0, int2 p1) { return dot(p0, p1); }
27
28// CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].sdot.v3i32(<3 x i32>
29// CHECK: ret i32 %hlsl.dot
30int test_dot_int3(int3 p0, int3 p1) { return dot(p0, p1); }
31
32// CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].sdot.v4i32(<4 x i32>
33// CHECK: ret i32 %hlsl.dot
34int test_dot_int4(int4 p0, int4 p1) { return dot(p0, p1); }
35
36// CHECK: %hlsl.dot = mul i32
37// CHECK: ret i32 %hlsl.dot
38uint test_dot_uint(uint p0, uint p1) { return dot(p0, p1); }
39
40// CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].udot.v2i32(<2 x i32>
41// CHECK: ret i32 %hlsl.dot
42uint test_dot_uint2(uint2 p0, uint2 p1) { return dot(p0, p1); }
43
44// CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].udot.v3i32(<3 x i32>
45// CHECK: ret i32 %hlsl.dot
46uint test_dot_uint3(uint3 p0, uint3 p1) { return dot(p0, p1); }
47
48// CHECK: %hlsl.dot = call i32 @llvm.[[ICF]].udot.v4i32(<4 x i32>
49// CHECK: ret i32 %hlsl.dot
50uint test_dot_uint4(uint4 p0, uint4 p1) { return dot(p0, p1); }
51
52// CHECK: %hlsl.dot = mul i64
53// CHECK: ret i64 %hlsl.dot
54int64_t test_dot_long(int64_t p0, int64_t p1) { return dot(p0, p1); }
55
56// CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].sdot.v2i64(<2 x i64>
57// CHECK: ret i64 %hlsl.dot
58int64_t test_dot_long2(int64_t2 p0, int64_t2 p1) { return dot(p0, p1); }
59
60// CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].sdot.v3i64(<3 x i64>
61// CHECK: ret i64 %hlsl.dot
62int64_t test_dot_long3(int64_t3 p0, int64_t3 p1) { return dot(p0, p1); }
63
64// CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].sdot.v4i64(<4 x i64>
65// CHECK: ret i64 %hlsl.dot
66int64_t test_dot_long4(int64_t4 p0, int64_t4 p1) { return dot(p0, p1); }
67
68// CHECK:  %hlsl.dot = mul i64
69// CHECK: ret i64 %hlsl.dot
70uint64_t test_dot_ulong(uint64_t p0, uint64_t p1) { return dot(p0, p1); }
71
72// CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].udot.v2i64(<2 x i64>
73// CHECK: ret i64 %hlsl.dot
74uint64_t test_dot_ulong2(uint64_t2 p0, uint64_t2 p1) { return dot(p0, p1); }
75
76// CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].udot.v3i64(<3 x i64>
77// CHECK: ret i64 %hlsl.dot
78uint64_t test_dot_ulong3(uint64_t3 p0, uint64_t3 p1) { return dot(p0, p1); }
79
80// CHECK: %hlsl.dot = call i64 @llvm.[[ICF]].udot.v4i64(<4 x i64>
81// CHECK: ret i64 %hlsl.dot
82uint64_t test_dot_ulong4(uint64_t4 p0, uint64_t4 p1) { return dot(p0, p1); }
83
84#ifdef __HLSL_ENABLE_16_BIT
85// NATIVE_HALF: %hlsl.dot = mul i16
86// NATIVE_HALF: ret i16 %hlsl.dot
87int16_t test_dot_short(int16_t p0, int16_t p1) { return dot(p0, p1); }
88
89// NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].sdot.v2i16(<2 x i16>
90// NATIVE_HALF: ret i16 %hlsl.dot
91int16_t test_dot_short2(int16_t2 p0, int16_t2 p1) { return dot(p0, p1); }
92
93// NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].sdot.v3i16(<3 x i16>
94// NATIVE_HALF: ret i16 %hlsl.dot
95int16_t test_dot_short3(int16_t3 p0, int16_t3 p1) { return dot(p0, p1); }
96
97// NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].sdot.v4i16(<4 x i16>
98// NATIVE_HALF: ret i16 %hlsl.dot
99int16_t test_dot_short4(int16_t4 p0, int16_t4 p1) { return dot(p0, p1); }
100
101// NATIVE_HALF: %hlsl.dot = mul i16
102// NATIVE_HALF: ret i16 %hlsl.dot
103uint16_t test_dot_ushort(uint16_t p0, uint16_t p1) { return dot(p0, p1); }
104
105// NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].udot.v2i16(<2 x i16>
106// NATIVE_HALF: ret i16 %hlsl.dot
107uint16_t test_dot_ushort2(uint16_t2 p0, uint16_t2 p1) { return dot(p0, p1); }
108
109// NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].udot.v3i16(<3 x i16>
110// NATIVE_HALF: ret i16 %hlsl.dot
111uint16_t test_dot_ushort3(uint16_t3 p0, uint16_t3 p1) { return dot(p0, p1); }
112
113// NATIVE_HALF: %hlsl.dot = call i16 @llvm.[[ICF]].udot.v4i16(<4 x i16>
114// NATIVE_HALF: ret i16 %hlsl.dot
115uint16_t test_dot_ushort4(uint16_t4 p0, uint16_t4 p1) { return dot(p0, p1); }
116#endif
117
118// NATIVE_HALF: %hlsl.dot = fmul reassoc nnan ninf nsz arcp afn half
119// NATIVE_HALF: ret half %hlsl.dot
120// NO_HALF: %hlsl.dot = fmul reassoc nnan ninf nsz arcp afn float
121// NO_HALF: ret float %hlsl.dot
122half test_dot_half(half p0, half p1) { return dot(p0, p1); }
123
124// NATIVE_HALF: %hlsl.dot = call reassoc nnan ninf nsz arcp afn half @llvm.[[ICF]].fdot.v2f16(<2 x half>
125// NATIVE_HALF: ret half %hlsl.dot
126// NO_HALF: %hlsl.dot = call reassoc nnan ninf nsz arcp afn float @llvm.[[ICF]].fdot.v2f32(<2 x float>
127// NO_HALF: ret float %hlsl.dot
128half test_dot_half2(half2 p0, half2 p1) { return dot(p0, p1); }
129
130// NATIVE_HALF: %hlsl.dot = call reassoc nnan ninf nsz arcp afn half @llvm.[[ICF]].fdot.v3f16(<3 x half>
131// NATIVE_HALF: ret half %hlsl.dot
132// NO_HALF: %hlsl.dot = call reassoc nnan ninf nsz arcp afn float @llvm.[[ICF]].fdot.v3f32(<3 x float>
133// NO_HALF: ret float %hlsl.dot
134half test_dot_half3(half3 p0, half3 p1) { return dot(p0, p1); }
135
136// NATIVE_HALF: %hlsl.dot = call reassoc nnan ninf nsz arcp afn half @llvm.[[ICF]].fdot.v4f16(<4 x half>
137// NATIVE_HALF: ret half %hlsl.dot
138// NO_HALF: %hlsl.dot = call reassoc nnan ninf nsz arcp afn float @llvm.[[ICF]].fdot.v4f32(<4 x float>
139// NO_HALF: ret float %hlsl.dot
140half test_dot_half4(half4 p0, half4 p1) { return dot(p0, p1); }
141
142// CHECK: %hlsl.dot = fmul reassoc nnan ninf nsz arcp afn float
143// CHECK: ret float %hlsl.dot
144float test_dot_float(float p0, float p1) { return dot(p0, p1); }
145
146// CHECK: %hlsl.dot = call reassoc nnan ninf nsz arcp afn float @llvm.[[ICF]].fdot.v2f32(<2 x float>
147// CHECK: ret float %hlsl.dot
148float test_dot_float2(float2 p0, float2 p1) { return dot(p0, p1); }
149
150// CHECK: %hlsl.dot = call reassoc nnan ninf nsz arcp afn float @llvm.[[ICF]].fdot.v3f32(<3 x float>
151// CHECK: ret float %hlsl.dot
152float test_dot_float3(float3 p0, float3 p1) { return dot(p0, p1); }
153
154// CHECK: %hlsl.dot = call reassoc nnan ninf nsz arcp afn float @llvm.[[ICF]].fdot.v4f32(<4 x float>
155// CHECK: ret float %hlsl.dot
156float test_dot_float4(float4 p0, float4 p1) { return dot(p0, p1); }
157
158// CHECK: %hlsl.dot = fmul reassoc nnan ninf nsz arcp afn double
159// CHECK: ret double %hlsl.dot
160double test_dot_double(double p0, double p1) { return dot(p0, p1); }
161