[clang] [HLSL] Fix casting asserts (PR #82827)
Farzon Lotfi via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 26 08:58:34 PST 2024
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/82827
>From 15eee3edd9ad834dc46fb5a1053874093b41a65a Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzon at farzon.org>
Date: Fri, 23 Feb 2024 15:28:13 -0500
Subject: [PATCH 1/2] [HLSL] Fix casting asserts There are two issues here.
first ICK_Floating_Integral were always defaulting to CK_FloatingToIntegral
for vectors regardless of direction of cast. Check was scalar only so added
a vec float check to the conditional. Second issue was float to int casts
were resolving to ICK_Integral_Promotion when they need to be resolving to
CK_FloatingToIntegral. This was fixed by changing the ordering of conversion
checks.
This fixes #82826
---
clang/lib/Sema/SemaExprCXX.cpp | 2 +-
clang/lib/Sema/SemaOverload.cpp | 14 +++---
.../SemaHLSL/VectorOverloadResolution.hlsl | 44 +++++++++++++++++++
3 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 322bd1c87b1d71..99f8abf77c0cb6 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -4843,7 +4843,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
.get();
break;
case ICK_Floating_Integral:
- if (ToType->isRealFloatingType())
+ if (ToType->isRealFloatingType() || ToType->hasFloatingRepresentation())
From =
ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue,
/*BasePath=*/nullptr, CCK)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f7645422348b65..ecad2b96816553 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1884,6 +1884,13 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType,
return true;
}
+ if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) ||
+ (FromType->isIntegralOrUnscopedEnumerationType() &&
+ ToType->isRealFloatingType())) {
+ ICK = ICK_Floating_Integral;
+ return true;
+ }
+
if (S.IsIntegralPromotion(From, FromType, ToType)) {
ICK = ICK_Integral_Promotion;
return true;
@@ -1895,13 +1902,6 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType,
return true;
}
- if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) ||
- (FromType->isIntegralOrUnscopedEnumerationType() &&
- ToType->isRealFloatingType())) {
- ICK = ICK_Floating_Integral;
- return true;
- }
-
return false;
}
diff --git a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl
index e07391f803f899..d8794ef675768b 100644
--- a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl
+++ b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl
@@ -1,4 +1,8 @@
// RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-library -S -fnative-half-type -finclude-default-header -o - -ast-dump %s | FileCheck %s
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s \
+// RUN: --check-prefixes=CHECKIR
void Fn(double2 D);
void Fn(half2 H);
@@ -28,3 +32,43 @@ void Fn2(int16_t2 S);
void Call2(int2 I) {
Fn2(I);
}
+
+void Fn3( int64_t2 p0);
+
+// CHECK: FunctionDecl {{.*}} Call3 'void (half2)'
+// CHECK: CallExpr {{.*}} 'void'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' <FunctionToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' <FloatingToIntegral>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'half2':'half __attribute__((ext_vector_type(2)))'
+// CHECKIR: %conv = fptosi <2 x half> %0 to <2 x i64>
+void Call3(half2 p0) {
+ Fn3(p0);
+}
+
+// CHECK: FunctionDecl {{.*}} Call4 'void (float2)'
+// CHECK: CallExpr {{.*}} 'void'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' <FunctionToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' <FloatingToIntegral>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'float2':'float __attribute__((ext_vector_type(2)))'
+// CHECKIR: %conv = fptosi <2 x float> %0 to <2 x i64>
+void Call4(float2 p0) {
+ Fn3(p0);
+}
+
+void Fn4( float2 p0);
+
+// CHECK: FunctionDecl {{.*}} Call5 'void (int64_t2)'
+// CHECK: CallExpr {{.*}} 'void'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'Fn4' 'void (float2)'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' <IntegralToFloating>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'int64_t2':'long __attribute__((ext_vector_type(2)))'
+// CHECKIR: %conv = sitofp <2 x i64> %0 to <2 x float>
+void Call5(int64_t2 p0) {
+ Fn4(p0);
+}
>From 0ff2c7162d2676190b5ad370b7e7171581d8d21b Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzon at farzon.org>
Date: Fri, 23 Feb 2024 15:28:13 -0500
Subject: [PATCH 2/2] [HLSL] Fix casting asserts There are two issues here.
first ICK_Floating_Integral were always defaulting to CK_FloatingToIntegral
for vectors regardless of direction of cast. Check was scalar only so added
a vec float check to the conditional. Second issue was float to int casts
were resolving to ICK_Integral_Promotion when they need to be resolving to
CK_FloatingToIntegral. This was fixed by changing the ordering of conversion
checks.
This fixes #82826
---
clang/lib/Sema/SemaExprCXX.cpp | 2 +-
clang/lib/Sema/SemaOverload.cpp | 14 +++----
.../SemaHLSL/VectorOverloadResolution.hlsl | 41 +++++++++++++++++++
3 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 322bd1c87b1d71..59758d3bd6d1a3 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -4843,7 +4843,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
.get();
break;
case ICK_Floating_Integral:
- if (ToType->isRealFloatingType())
+ if (ToType->hasFloatingRepresentation())
From =
ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue,
/*BasePath=*/nullptr, CCK)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f7645422348b65..ecad2b96816553 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1884,6 +1884,13 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType,
return true;
}
+ if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) ||
+ (FromType->isIntegralOrUnscopedEnumerationType() &&
+ ToType->isRealFloatingType())) {
+ ICK = ICK_Floating_Integral;
+ return true;
+ }
+
if (S.IsIntegralPromotion(From, FromType, ToType)) {
ICK = ICK_Integral_Promotion;
return true;
@@ -1895,13 +1902,6 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType,
return true;
}
- if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) ||
- (FromType->isIntegralOrUnscopedEnumerationType() &&
- ToType->isRealFloatingType())) {
- ICK = ICK_Floating_Integral;
- return true;
- }
-
return false;
}
diff --git a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl
index e07391f803f899..c9adc36ca5e705 100644
--- a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl
+++ b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-library -S -fnative-half-type -finclude-default-header -o - -ast-dump %s | FileCheck %s
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s --check-prefixes=CHECKIR
void Fn(double2 D);
void Fn(half2 H);
@@ -28,3 +29,43 @@ void Fn2(int16_t2 S);
void Call2(int2 I) {
Fn2(I);
}
+
+void Fn3( int64_t2 p0);
+
+// CHECK: FunctionDecl {{.*}} Call3 'void (half2)'
+// CHECK: CallExpr {{.*}} 'void'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' <FunctionToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' <FloatingToIntegral>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'half2':'half __attribute__((ext_vector_type(2)))'
+// CHECKIR: %conv = fptosi <2 x half> %0 to <2 x i64>
+void Call3(half2 p0) {
+ Fn3(p0);
+}
+
+// CHECK: FunctionDecl {{.*}} Call4 'void (float2)'
+// CHECK: CallExpr {{.*}} 'void'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' <FunctionToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' <FloatingToIntegral>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'float2':'float __attribute__((ext_vector_type(2)))'
+// CHECKIR: %conv = fptosi <2 x float> %0 to <2 x i64>
+void Call4(float2 p0) {
+ Fn3(p0);
+}
+
+void Fn4( float2 p0);
+
+// CHECK: FunctionDecl {{.*}} Call5 'void (int64_t2)'
+// CHECK: CallExpr {{.*}} 'void'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'Fn4' 'void (float2)'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' <IntegralToFloating>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'int64_t2':'long __attribute__((ext_vector_type(2)))'
+// CHECKIR: %conv = sitofp <2 x i64> %0 to <2 x float>
+void Call5(int64_t2 p0) {
+ Fn4(p0);
+}
More information about the cfe-commits
mailing list