brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.3 KiB · a980cbd Raw
225 lines · plain
1// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -fnative-half-type -finclude-default-header -Wconversion -verify -o - %s -DERROR=12// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -fnative-half-type -finclude-default-header -Wno-conversion -ast-dump %s | FileCheck %s3 4// This test verifies floating point type implicit conversion ranks for overload5// resolution. In HLSL the built-in type ranks are half < float < double. This6// applies to both scalar and vector types.7 8// HLSL allows implicit truncation fo types, so it differentiates between9// promotions (converting to larger types) and conversions (converting to10// smaller types). Promotions are preferred over conversions. Promotions prefer11// promoting to the next lowest type in the ranking order. Conversions prefer12// converting to the next highest type in the ranking order.13 14void HalfFloatDouble(double2 D);15void HalfFloatDouble(float2 F);16void HalfFloatDouble(half2 H);17 18// CHECK: FunctionDecl {{.*}} used HalfFloatDouble 'void (double2)'19// CHECK: FunctionDecl {{.*}} used HalfFloatDouble 'void (float2)'20// CHECK: FunctionDecl {{.*}} used HalfFloatDouble 'void (half2)'21 22void FloatDouble(double2 D); // expected-note {{candidate function}}23void FloatDouble(float2 F); // expected-note {{candidate function}}24 25// CHECK: FunctionDecl {{.*}} used FloatDouble 'void (double2)'26// CHECK: FunctionDecl {{.*}} used FloatDouble 'void (float2)'27 28void HalfDouble(double2 D);29void HalfDouble(half2 H);30 31// CHECK: FunctionDecl {{.*}} used HalfDouble 'void (double2)'32// CHECK: FunctionDecl {{.*}} used HalfDouble 'void (half2)'33 34void HalfFloat(float2 F); // expected-note {{candidate function}}35void HalfFloat(half2 H); // expected-note {{candidate function}}36 37// CHECK: FunctionDecl {{.*}} used HalfFloat 'void (float2)'38// CHECK: FunctionDecl {{.*}} used HalfFloat 'void (half2)'39 40void Double(double2 D);41void Float(float2 F);42void Half(half2 H);43 44// CHECK: FunctionDecl {{.*}} used Double 'void (double2)'45// CHECK: FunctionDecl {{.*}} used Float 'void (float2)'46// CHECK: FunctionDecl {{.*}} used Half 'void (half2)'47 48// Case 1: A function declared with overloads for half float and double types.49//   (a) When called with half, it will resolve to half because half is an exact50//   match.51//   (b) When called with float it will resolve to float because float is an52//   exact match.53//   (c) When called with double it will resolve to double because it is an54//   exact match.55 56// CHECK-LABEL: FunctionDecl {{.*}} Case1 'void (half2, float2, double2)'57void Case1(half2 H, float2 F, double2 D) {58  // CHECK: CallExpr {{.*}} 'void'59  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half2)' <FunctionToPointerDecay>60  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half2)' lvalue Function {{.*}} 'HalfFloatDouble' 'void (half2)'61  HalfFloatDouble(H);62 63  // CHECK: CallExpr {{.*}} 'void'64  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>65  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'HalfFloatDouble' 'void (float2)'66  HalfFloatDouble(F);67 68  // CHECK: CallExpr {{.*}} 'void'69  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>70  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'HalfFloatDouble' 'void (double2)'71  HalfFloatDouble(D);72}73 74// Case 2: A function declared with double and float overlaods.75//   (a) When called with half, it fails to resulve the ambiguous promotion.76//   (b) When called with float it will resolve to float because float is an77//   exact match.78//   (c) When called with double it will resolve to double because it is an79//   exact match.80 81// CHECK-LABEL: FunctionDecl {{.*}} Case2 'void (half2, float2, double2)'82void Case2(half2 H, float2 F, double2 D) {83#if ERROR84  FloatDouble(H); // expected-error {{call to 'FloatDouble' is ambiguous}}85#endif86 87  // CHECK: CallExpr {{.*}} 'void'88  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>89  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'FloatDouble' 'void (float2)'90  FloatDouble(F);91 92  // CHECK: CallExpr {{.*}} 'void'93  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>94  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'FloatDouble' 'void (double2)'95  FloatDouble(D);96}97 98// Case 3: A function declared with half and double overloads99//   (a) When called with half, it will resolve to half because it is an exact100//   match.101//   (b) When called with flaot, it will resolve to double because double is a102//   valid promotion.103//   (c) When called with double, it will resolve to double because it is an104//   exact match.105 106// CHECK-LABEL: FunctionDecl {{.*}} Case3 'void (half2, float2, double2)'107void Case3(half2 H, float2 F, double2 D) {108  // CHECK: CallExpr {{.*}} 'void'109  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half2)' <FunctionToPointerDecay>110  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half2)' lvalue Function {{.*}} 'HalfDouble' 'void (half2)'111  HalfDouble(H);112 113  // CHECK: CallExpr {{.*}} 'void'114  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>115  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'HalfDouble' 'void (double2)'116  HalfDouble(F);117 118  // CHECK: CallExpr {{.*}} 'void'119  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>120  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'HalfDouble' 'void (double2)'121  HalfDouble(D);122}123 124// Case 4: A function declared with half and float overloads.125//   (a) When called with half, it will resolve to half because half is an exact126//   match.127//   (b) When called with float it will resolve to float because float is an128//   exact match.129//   (c) When called with double it fails to resolve the ambigjuous conversion.130 131// CHECK-LABEL: FunctionDecl {{.*}} Case4 'void (half2, float2, double2)'132void Case4(half2 H, float2 F, double2 D) {133  // CHECK: CallExpr {{.*}} 'void'134  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half2)' <FunctionToPointerDecay>135  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half2)' lvalue Function {{.*}} 'HalfFloat' 'void (half2)'136  HalfFloat(H);137 138  // CHECK: CallExpr {{.*}} 'void'139  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>140  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'HalfFloat' 'void (float2)'141  HalfFloat(F);142 143#if ERROR144  HalfFloat(D); // expected-error{{call to 'HalfFloat' is ambiguous}}145#endif146}147 148// Case 5: A function declared with only a double overload.149//   (a) When called with half, it will resolve to double because double is a150//   valid promotion.151//   (b) When called with float it will resolve to double because double is a152//   valid promotion.153//   (c) When called with double it will resolve to double because it is an154//   exact match.155 156// CHECK-LABEL: FunctionDecl {{.*}} Case5 'void (half2, float2, double2)'157void Case5(half2 H, float2 F, double2 D) {158  // CHECK: CallExpr {{.*}} 'void'159  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>160  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'Double' 'void (double2)'161  Double(H);162 163  // CHECK: CallExpr {{.*}} 'void'164  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>165  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'Double' 'void (double2)'166  Double(F);167 168  // CHECK: CallExpr {{.*}} 'void'169  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double2)' <FunctionToPointerDecay>170  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double2)' lvalue Function {{.*}} 'Double' 'void (double2)'171  Double(D);172}173 174// Case 6: A function declared with only a float overload.175//   (a) When called with half, it will resolve to float because float is a176//   valid promotion.177//   (b) When called with float it will resolve to float because float is an178//   exact match.179//   (c) When called with double it will resolve to float because it is a180//   valid conversion.181 182// CHECK-LABEL: FunctionDecl {{.*}} Case6 'void (half2, float2, double2)'183void Case6(half2 H, float2 F, double2 D) {184  // CHECK: CallExpr {{.*}} 'void'185  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>186  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'Float' 'void (float2)'187  Float(H);188 189  // CHECK: CallExpr {{.*}} 'void'190  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>191  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'Float' 'void (float2)'192  Float(F);193 194  // CHECK: CallExpr {{.*}} 'void'195  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>196  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'Float' 'void (float2)'197  Float(D); // expected-warning{{implicit conversion loses floating-point precision: 'double2' (aka 'vector<double, 2>') to 'vector<float, 2>' (vector of 2 'float' values)}}198}199 200// Case 7: A function declared with only a half overload.201//   (a) When called with half, it will resolve to half because half is an202//   exact match203//   (b) When called with float it will resolve to half because half is a204//   valid conversion.205//   (c) When called with double it will resolve to float because it is a206//   valid conversion.207 208// CHECK-LABEL: FunctionDecl {{.*}} Case7 'void (half2, float2, double2)'209void Case7(half2 H, float2 F, double2 D) {210  // CHECK: CallExpr {{.*}} 'void'211  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half2)' <FunctionToPointerDecay>212  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half2)' lvalue Function {{.*}} 'Half' 'void (half2)'213  Half(H);214 215  // CHECK: CallExpr {{.*}} 'void'216  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half2)' <FunctionToPointerDecay>217  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half2)' lvalue Function {{.*}} 'Half' 'void (half2)'218  Half(F); // expected-warning{{implicit conversion loses floating-point precision: 'float2' (aka 'vector<float, 2>') to 'vector<half, 2>' (vector of 2 'half' values)}}219 220  // CHECK: CallExpr {{.*}} 'void'221  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half2)' <FunctionToPointerDecay>222  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half2)' lvalue Function {{.*}} 'Half' 'void (half2)'223  Half(D); // expected-warning{{implicit conversion loses floating-point precision: 'double2' (aka 'vector<double, 2>') to 'vector<half, 2>' (vector of 2 'half' values)}}224}225