[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaHLSL / SplatOverloadResolution.hlsl
blobf0798dfc724970e5dba4aa81ee695fbfd8d0a1e4
1 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -fnative-half-type -finclude-default-header -fsyntax-only %s -DERROR=1 -verify
2 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -fnative-half-type -finclude-default-header -ast-dump %s | FileCheck %s
5 // Case 1: Prioritize splat without conversion over conversion. In this case the
6 // called functions have valid overloads for each type, however one of the
7 // overloads is a vector rather than scalar. Each call should resolve to the
8 // same type, and the vector should splat.
9 void HalfFloatDoubleV(double2 D);
10 void HalfFloatDoubleV(float F);
11 void HalfFloatDoubleV(half H);
13 void HalfFloatVDouble(double D);
14 void HalfFloatVDouble(float2 F);
15 void HalfFloatVDouble(half H);
17 void HalfVFloatDouble(double D);
18 void HalfVFloatDouble(float F);
19 void HalfVFloatDouble(half2 H);
22 // CHECK-LABEL: FunctionDecl {{.*}} Case1 'void (half, float, double)'
23 void Case1(half H, float F, double D) {
24   // CHECK: CallExpr {{.*}} 'void'
25   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>
26   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'HalfFloatDoubleV' 'void (half)'
27   HalfFloatDoubleV(H);
29   // CHECK: CallExpr {{.*}} 'void'
30   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>
31   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'HalfFloatDoubleV' 'void (float)'
32   HalfFloatDoubleV(F);
34   // CHECK: CallExpr {{.*}} 'void'
35   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>
36   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'HalfFloatDoubleV' 'void (double2)'
37   HalfFloatDoubleV(D);
39   // CHECK: CallExpr {{.*}} 'void'
40   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>
41   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'HalfFloatVDouble' 'void (half)'
42   HalfFloatVDouble(H);
44   // CHECK: CallExpr {{.*}} 'void'
45   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>
46   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'HalfFloatVDouble' 'void (float2)'
47   HalfFloatVDouble(F);
49   // CHECK: CallExpr {{.*}} 'void'
50   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>
51   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'HalfFloatVDouble' 'void (double)'
52   HalfFloatVDouble(D);
54   // CHECK: CallExpr {{.*}} 'void'
55   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half2)' <FunctionToPointerDecay>
56   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half2)' lvalue Function {{.*}} 'HalfVFloatDouble' 'void (half2)'
57   HalfVFloatDouble(H);
59   // CHECK: CallExpr {{.*}} 'void'
60   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>
61   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'HalfVFloatDouble' 'void (float)'
62   HalfVFloatDouble(F);
64   // CHECK: CallExpr {{.*}} 'void'
65   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>
66   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'HalfVFloatDouble' 'void (double)'
67   HalfVFloatDouble(D);
70 // Case 2: Prefer splat+promotion over conversion. In this case the overloads
71 // require a splat+promotion or a conversion. The call will resolve to the
72 // splat+promotion.
73 void HalfDoubleV(double2 D);
74 void HalfDoubleV(half H);
76 // CHECK-LABEL: FunctionDecl {{.*}} Case2 'void (float)'
77 void Case2(float F) {
78   // CHECK: CallExpr {{.*}} 'void'
79   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>
80   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'HalfDoubleV' 'void (double2)'
81   HalfDoubleV(F);
84 // Case 3: Prefer promotion or conversion without splat over the splat. In this
85 // case the scalar value will overload to the scalar function.
86 void DoubleV(double D);
87 void DoubleV(double2 V);
89 void HalfV(half D);
90 void HalfV(half2 V);
92 // CHECK-LABEL: FunctionDecl {{.*}} Case3 'void (float)'
93 void Case3(float F) {
94   // CHECK: CallExpr {{.*}} 'void'
95   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>
96   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'DoubleV' 'void (double)'
97   DoubleV(F);
99   // CHECK: CallExpr {{.*}} 'void'
100   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>
101   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'HalfV' 'void (half)'
102   HalfV(F);
105 #if ERROR
106 // Case 4: It is ambiguous to resolve two splat+conversion or splat+promotion
107 // functions. In all the calls below an error occurs.
108 void FloatVDoubleV(float2 F); // expected-note {{candidate function}}
109 void FloatVDoubleV(double2 D); // expected-note {{candidate function}}
111 void HalfVFloatV(half2 H); // expected-note {{candidate function}}
112 void HalfVFloatV(float2 F); // expected-note {{candidate function}}
114 void Case4(half H, double D) {
115   FloatVDoubleV(H); // expected-error {{call to 'FloatVDoubleV' is ambiguous}}
117   HalfVFloatV(D); // expected-error {{call to 'HalfVFloatV' is ambiguous}}
120 // Case 5: It is ambiguous to resolve two splats of different lengths.
121 void FloatV(float2 V); // expected-note {{candidate function}} expected-note {{candidate function}} expected-note {{candidate function}}
122 void FloatV(float4 V); // expected-note {{candidate function}} expected-note {{candidate function}} expected-note {{candidate function}}
124 void Case5(half H, float F, double D) {
125   FloatV(H); // expected-error {{call to 'FloatV' is ambiguous}}
126   FloatV(F); // expected-error {{call to 'FloatV' is ambiguous}}
127   FloatV(D); // expected-error {{call to 'FloatV' is ambiguous}}
129 #endif
131 // Case 5: Vectors truncate or match, but don't extend.
132 void FloatV24(float2 V);
133 void FloatV24(float4 V);
135 // CHECK-LABEL: FunctionDecl {{.*}} Case5 'void (half3, float3, double3, half4, float4, double4)'
136 void Case5(half3 H3, float3 F3, double3 D3, half4 H4, float4 F4, double4 D4) {
137   // CHECK: CallExpr {{.*}} 'void'
138   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>
139   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'FloatV24' 'void (float2)'
140   FloatV24(H3); // expected-warning{{implicit conversion truncates vector: 'half3' (aka 'vector<half, 3>') to 'vector<float, 2>' (vector of 2 'float' values)}}
142   // CHECK: CallExpr {{.*}} 'void'
143   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>
144   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'FloatV24' 'void (float2)'
145   FloatV24(F3); // expected-warning{{implicit conversion truncates vector: 'float3' (aka 'vector<float, 3>') to 'vector<float, 2>' (vector of 2 'float' values)}}
147   // CHECK: CallExpr {{.*}} 'void'
148   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>
149   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'FloatV24' 'void (float2)'
150   FloatV24(D3); // expected-warning{{implicit conversion truncates vector: 'double3' (aka 'vector<double, 3>') to 'vector<float, 2>' (vector of 2 'float' values)}}
152   // CHECK: CallExpr {{.*}} 'void'
153   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float4)' <FunctionToPointerDecay>
154   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float4)' lvalue Function {{.*}} 'FloatV24' 'void (float4)'
155   FloatV24(H4);
157   // CHECK: CallExpr {{.*}} 'void'
158   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float4)' <FunctionToPointerDecay>
159   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float4)' lvalue Function {{.*}} 'FloatV24' 'void (float4)'
160   FloatV24(F4);
162   // CHECK: CallExpr {{.*}} 'void'
163   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float4)' <FunctionToPointerDecay>
164   // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float4)' lvalue Function {{.*}} 'FloatV24' 'void (float4)'
165   FloatV24(D4);