Skip to content

Commit 8ebbb20

Browse files
authored
[HLSL] Add an lvalue to rvalue cast when appropriate for HLSLElementwiseCast and HLSLAggregateSplatCast (#163828)
When the Sub expression of an HLSLAggregateSplatCast is an LValue insert an LValue to RValue cast; done using DefaultLvalueConversion. When the Sub expression of an HLSLElementwiseCast is an LValue and not a record or an array insert an LValue to RValue cast. Arrays were already handled correctly using an HLSLArrayRValue cast. DefaultLvalueConversion is used to add the LValue to RValue cast when appropriate and does not emit one when the expression is a record. Update existing test which was broken by this change. Add two new tests for HLSLElementwiseCast showing the lack of lvalue to rvalue cast for a struct and showing the lvalue to rvalue cast for a vector. Closes #163593
1 parent a0b66b5 commit 8ebbb20

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

clang/lib/Sema/SemaCast.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2927,6 +2927,8 @@ bool CastOperation::CheckHLSLCStyleCast(CheckedConversionKind CCK) {
29272927
SrcExpr = Self.ImpCastExprToType(
29282928
SrcExpr.get(), Self.Context.getArrayParameterType(SrcTy),
29292929
CK_HLSLArrayRValue, VK_PRValue, nullptr, CCK);
2930+
else
2931+
SrcExpr = Self.DefaultLvalueConversion(SrcExpr.get());
29302932
Kind = CK_HLSLElementwiseCast;
29312933
return true;
29322934
}
@@ -2935,6 +2937,7 @@ bool CastOperation::CheckHLSLCStyleCast(CheckedConversionKind CCK) {
29352937
// If the relative order of this and the HLSLElementWise cast checks
29362938
// are changed, it might change which cast handles what in a few cases
29372939
if (Self.HLSL().CanPerformAggregateSplatCast(SrcExpr.get(), DestType)) {
2940+
SrcExpr = Self.DefaultLvalueConversion(SrcExpr.get());
29382941
const VectorType *VT = SrcTy->getAs<VectorType>();
29392942
// change splat from vec1 case to splat from scalar
29402943
if (VT && VT->getNumElements() == 1)

clang/test/SemaHLSL/Language/AggregateSplatCasts.hlsl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
// splat from vec1 to vec
44
// CHECK-LABEL: call1
55
// CHECK: CStyleCastExpr {{.*}} 'int3':'vector<int, 3>' <HLSLAggregateSplatCast>
6-
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' lvalue <FloatingToIntegral> part_of_explicit_cast
7-
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' lvalue <HLSLVectorTruncation> part_of_explicit_cast
6+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <FloatingToIntegral> part_of_explicit_cast
7+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <HLSLVectorTruncation> part_of_explicit_cast
8+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float1':'vector<float, 1>' <LValueToRValue> part_of_explicit_cast
89
// CHECK-NEXT: DeclRefExpr {{.*}} 'float1':'vector<float, 1>' lvalue Var {{.*}} 'A' 'float1':'vector<float, 1>'
910
export void call1() {
1011
float1 A = {1.0};
@@ -21,7 +22,7 @@ struct S {
2122
// splat from scalar to aggregate
2223
// CHECK-LABEL: call2
2324
// CHECK: CStyleCastExpr {{.*}} 'S' <HLSLAggregateSplatCast>
24-
// CHECK-NEXt: IntegerLiteral {{.*}} 'int' 5
25+
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5
2526
export void call2() {
2627
S s = (S)5;
2728
}

clang/test/SemaHLSL/Language/ElementwiseCasts.hlsl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,27 @@ export void call2() {
2121
float B[1] = {1.0};
2222
B = (float[1])A;
2323
}
24+
25+
struct S {
26+
int A;
27+
float F;
28+
};
29+
30+
// cast from a struct
31+
// CHECK-LABEL: call3
32+
// CHECK: CStyleCastExpr {{.*}} 'int[2]' <HLSLElementwiseCast>
33+
// CHECK-NEXT: DeclRefExpr {{.*}} 'S' lvalue Var {{.*}} 'SS' 'S'
34+
export void call3() {
35+
S SS = {1,1.0};
36+
int A[2] = (int[2])SS;
37+
}
38+
39+
// cast from a vector
40+
// CHECK-LABEL: call4
41+
// CHECK: CStyleCastExpr {{.*}} 'float[3]' <HLSLElementwiseCast>
42+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int3':'vector<int, 3>' <LValueToRValue> part_of_explicit_cast
43+
// CHECK-NEXT: DeclRefExpr {{.*}} 'int3':'vector<int, 3>' lvalue Var {{.*}} 'A' 'int3'
44+
export void call4() {
45+
int3 A = {1,2,3};
46+
float B[3] = (float[3])A;
47+
}

0 commit comments

Comments
 (0)