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)'
29 // CHECK: CallExpr {{.*}} 'void'
30 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>
31 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'HalfFloatDoubleV' 'void (float)'
34 // CHECK: CallExpr {{.*}} 'void'
35 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>
36 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'HalfFloatDoubleV' 'void (double2)'
39 // CHECK: CallExpr {{.*}} 'void'
40 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>
41 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'HalfFloatVDouble' 'void (half)'
44 // CHECK: CallExpr {{.*}} 'void'
45 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>
46 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'HalfFloatVDouble' 'void (float2)'
49 // CHECK: CallExpr {{.*}} 'void'
50 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>
51 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'HalfFloatVDouble' 'void (double)'
54 // CHECK: CallExpr {{.*}} 'void'
55 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half2)' <FunctionToPointerDecay>
56 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half2)' lvalue Function {{.*}} 'HalfVFloatDouble' 'void (half2)'
59 // CHECK: CallExpr {{.*}} 'void'
60 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>
61 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'HalfVFloatDouble' 'void (float)'
64 // CHECK: CallExpr {{.*}} 'void'
65 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>
66 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'HalfVFloatDouble' 'void (double)'
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
73 void HalfDoubleV(double2 D);
74 void HalfDoubleV(half H);
76 // CHECK-LABEL: FunctionDecl {{.*}} Case2 'void (float)'
78 // CHECK: CallExpr {{.*}} 'void'
79 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>
80 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'HalfDoubleV' 'void (double2)'
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);
92 // CHECK-LABEL: FunctionDecl {{.*}} Case3 'void (float)'
94 // CHECK: CallExpr {{.*}} 'void'
95 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>
96 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'DoubleV' 'void (double)'
99 // CHECK: CallExpr {{.*}} 'void'
100 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>
101 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'HalfV' 'void (half)'
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}}
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)'
157 // CHECK: CallExpr {{.*}} 'void'
158 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float4)' <FunctionToPointerDecay>
159 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float4)' lvalue Function {{.*}} 'FloatV24' 'void (float4)'
162 // CHECK: CallExpr {{.*}} 'void'
163 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float4)' <FunctionToPointerDecay>
164 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float4)' lvalue Function {{.*}} 'FloatV24' 'void (float4)'