brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.0 KiB · 77090b7 Raw
228 lines · plain
1// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -fnative-half-type -finclude-default-header -Wconversion -verify -o - -DERROR=1 %s2// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -fnative-half-type -finclude-default-header -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(double D);15void HalfFloatDouble(float F);16void HalfFloatDouble(half H);17 18// CHECK: FunctionDecl {{.*}} used HalfFloatDouble 'void (double)'19// CHECK: FunctionDecl {{.*}} used HalfFloatDouble 'void (float)'20// CHECK: FunctionDecl {{.*}} used HalfFloatDouble 'void (half)'21 22void FloatDouble(double D); // expected-note{{candidate function}}23void FloatDouble(float F); // expected-note{{candidate function}}24 25// CHECK: FunctionDecl {{.*}} used FloatDouble 'void (double)'26// CHECK: FunctionDecl {{.*}} used FloatDouble 'void (float)'27 28void HalfDouble(double D);29void HalfDouble(half H);30 31// CHECK: FunctionDecl {{.*}} used HalfDouble 'void (double)'32// CHECK: FunctionDecl {{.*}} used HalfDouble 'void (half)'33 34void HalfFloat(float F); // expected-note{{candidate function}}35void HalfFloat(half H); // expected-note{{candidate function}}36 37// CHECK: FunctionDecl {{.*}} used HalfFloat 'void (float)'38// CHECK: FunctionDecl {{.*}} used HalfFloat 'void (half)'39 40void Double(double D);41void Float(float F);42void Half(half H);43 44// CHECK: FunctionDecl {{.*}} used Double 'void (double)'45// CHECK: FunctionDecl {{.*}} used Float 'void (float)'46// CHECK: FunctionDecl {{.*}} used Half 'void (half)'47 48 49// Case 1: A function declared with overloads for half float and double types.50//   (a) When called with half, it will resolve to half because half is an exact51//   match.52//   (b) When called with float it will resolve to float because float is an53//   exact match.54//   (c) When called with double it will resolve to double because it is an55//   exact match.56 57// CHECK-LABEL: FunctionDecl {{.*}} Case1 'void (half, float, double)'58void Case1(half H, float F, double D) {59  // CHECK: CallExpr {{.*}} 'void'60  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>61  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'HalfFloatDouble' 'void (half)'62  HalfFloatDouble(H);63 64  // CHECK: CallExpr {{.*}} 'void'65  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>66  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'HalfFloatDouble' 'void (float)'67  HalfFloatDouble(F);68 69  // CHECK: CallExpr {{.*}} 'void'70  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>71  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'HalfFloatDouble' 'void (double)'72  HalfFloatDouble(D);73}74 75// Case 2: A function declared with double and float overlaods.76//   (a) When called with half, it will fail to resolve because it cannot77//   disambiguate the promotions.78//   (b) When called with float it will resolve to float because float is an79//   exact match.80//   (c) When called with double it will resolve to double because it is an81//   exact match.82 83// CHECK-LABEL: FunctionDecl {{.*}} Case2 'void (half, float, double)'84void Case2(half H, float F, double D) {85  #if ERROR86  FloatDouble(H); // expected-error{{call to 'FloatDouble' is ambiguous}}87  #endif88 89  // CHECK: CallExpr {{.*}} 'void'90  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>91  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'FloatDouble' 'void (float)'92  FloatDouble(F);93 94  // CHECK: CallExpr {{.*}} 'void'95  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>96  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'FloatDouble' 'void (double)'97  FloatDouble(D);98}99 100// Case 3: A function declared with half and double overloads101//   (a) When called with half, it will resolve to half because it is an exact102//   match.103//   (b) When called with flaot, it will resolve to double because double is a104//   valid promotion.105//   (c) When called with double, it will resolve to double because it is an106//   exact match.107 108// CHECK-LABEL: FunctionDecl {{.*}} Case3 'void (half, float, double)'109void Case3(half H, float F, double D) {110  // CHECK: CallExpr {{.*}} 'void'111  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>112  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'HalfDouble' 'void (half)'113  HalfDouble(H);114 115  // CHECK: CallExpr {{.*}} 'void'116  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>117  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'HalfDouble' 'void (double)'118  HalfDouble(F);119 120  // CHECK: CallExpr {{.*}} 'void'121  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>122  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'HalfDouble' 'void (double)'123  HalfDouble(D);124}125 126// Case 4: A function declared with half and float overloads.127//   (a) When called with half, it will resolve to half because half is an exact128//   match.129//   (b) When called with float it will resolve to float because float is an130//   exact match.131//   (c) When called with double it will resolve to float because it is the132//   float is higher rank than half.133 134// CHECK-LABEL: FunctionDecl {{.*}} Case4 'void (half, float, double)'135void Case4(half H, float F, double D) {136  // CHECK: CallExpr {{.*}} 'void'137  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>138  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'HalfFloat' 'void (half)'139  HalfFloat(H);140 141  // CHECK: CallExpr {{.*}} 'void'142  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>143  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'HalfFloat' 'void (float)'144  HalfFloat(F);145 146  #if ERROR147  HalfFloat(D); // expected-error{{call to 'HalfFloat' is ambiguous}}148  #endif149}150 151// Case 5: A function declared with only a double overload.152//   (a) When called with half, it will resolve to double because double is a153//   valid promotion.154//   (b) When called with float it will resolve to double because double is a155//   valid promotion.156//   (c) When called with double it will resolve to double because it is an157//   exact match.158 159// CHECK-LABEL: FunctionDecl {{.*}} Case5 'void (half, float, double)'160void Case5(half H, float F, double D) {161  // CHECK: CallExpr {{.*}} 'void'162  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>163  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'Double' 'void (double)'164  Double(H);165 166  // CHECK: CallExpr {{.*}} 'void'167  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>168  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'Double' 'void (double)'169  Double(F);170 171  // CHECK: CallExpr {{.*}} 'void'172  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(double)' <FunctionToPointerDecay>173  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (double)' lvalue Function {{.*}} 'Double' 'void (double)'174  Double(D);175}176 177// Case 6: A function declared with only a float overload.178//   (a) When called with half, it will resolve to float because float is a179//   valid promotion.180//   (b) When called with float it will resolve to float because float is an181//   exact match.182//   (c) When called with double it will resolve to float because it is a183//   valid conversion.184 185// CHECK-LABEL: FunctionDecl {{.*}} Case6 'void (half, float, double)'186void Case6(half H, float F, double D) {187  // CHECK: CallExpr {{.*}} 'void'188  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>189  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'Float' 'void (float)'190  Float(H);191 192  // CHECK: CallExpr {{.*}} 'void'193  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>194  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'Float' 'void (float)'195  Float(F);196 197  // CHECK: CallExpr {{.*}} 'void'198  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float)' <FunctionToPointerDecay>199  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (float)' lvalue Function {{.*}} 'Float' 'void (float)'200  Float(D); // expected-warning{{implicit conversion loses floating-point precision: 'double' to 'float'}}201}202 203// Case 7: A function declared with only a half overload.204//   (a) When called with half, it will resolve to half because half is an205//   exact match206//   (b) When called with float it will resolve to half because half is a207//   valid conversion.208//   (c) When called with double it will resolve to float because it is a209//   valid conversion.210 211// CHECK-LABEL: FunctionDecl {{.*}} Case7 'void (half, float, double)'212void Case7(half H, float F, double D) {213  // CHECK: CallExpr {{.*}} 'void'214  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>215  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'Half' 'void (half)'216  Half(H);217 218  // CHECK: CallExpr {{.*}} 'void'219  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>220  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'Half' 'void (half)'221  Half(F); // expected-warning{{implicit conversion loses floating-point precision: 'float' to 'half'}}222 223  // CHECK: CallExpr {{.*}} 'void'224  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(half)' <FunctionToPointerDecay>225  // CHECK-NEXT: DeclRefExpr {{.*}} 'void (half)' lvalue Function {{.*}} 'Half' 'void (half)'226  Half(D); // expected-warning{{implicit conversion loses floating-point precision: 'double' to 'half'}}227}228