Skip to content

Commit 5d81a4b

Browse files
committed
compare unqualified canonical types and add an hlsl array rvalue cast
1 parent 97dcbde commit 5d81a4b

File tree

3 files changed

+70
-17
lines changed

3 files changed

+70
-17
lines changed

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4418,19 +4418,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
44184418
case ICK_HLSL_Array_RValue:
44194419
if (ToType->isArrayParameterType()) {
44204420
FromType = Context.getArrayParameterType(FromType);
4421-
From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue,
4422-
/*BasePath=*/nullptr, CCK)
4423-
.get();
4424-
} else { // FromType must be ArrayParameterType
4425-
assert(FromType->isArrayParameterType() &&
4426-
"FromType must be ArrayParameterType in ICK_HLSL_Array_RValue \
4427-
if it is not ToType");
4421+
} else if (FromType->isArrayParameterType()) {
44284422
const ArrayParameterType *APT = cast<ArrayParameterType>(FromType);
44294423
FromType = APT->getConstantArrayType(Context);
4430-
From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue,
4431-
/*BasePath=*/nullptr, CCK)
4432-
.get();
44334424
}
4425+
From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue,
4426+
/*BasePath=*/nullptr, CCK)
4427+
.get();
44344428
break;
44354429

44364430
case ICK_Function_To_Pointer:

clang/lib/Sema/SemaOverload.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,17 +2268,15 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
22682268
// handling here.
22692269
if (ToType->isArrayParameterType()) {
22702270
FromType = S.Context.getArrayParameterType(FromType);
2271-
SCS.First = ICK_HLSL_Array_RValue;
22722271
} else if (FromType->isArrayParameterType()) {
22732272
const ArrayParameterType *APT = cast<ArrayParameterType>(FromType);
22742273
FromType = APT->getConstantArrayType(S.Context);
2275-
SCS.First = ICK_HLSL_Array_RValue;
2276-
} else {
2277-
SCS.First = ICK_Identity;
22782274
}
22792275

2280-
if (S.Context.getCanonicalType(FromType) !=
2281-
S.Context.getCanonicalType(ToType))
2276+
SCS.First = ICK_HLSL_Array_RValue;
2277+
2278+
if (FromType.getCanonicalType().getUnqualifiedType() !=
2279+
ToType.getCanonicalType().getUnqualifiedType())
22822280
return false;
22832281

22842282
SCS.setAllToTypes(ToType);

clang/test/CodeGenHLSL/ArrayAssignable.hlsl

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,23 @@
1-
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --enable-var-scope
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -finclude-default-header -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
2+
3+
struct S {
4+
int x;
5+
float f;
6+
};
7+
8+
// CHECK: [[CBLayout:%.*]] = type <{ [2 x float], [2 x <4 x i32>], [2 x [2 x i32]], [1 x target("dx.Layout", %S, 8, 0, 4)] }>
9+
// CHECK: @CBArrays.cb = global target("dx.CBuffer", target("dx.Layout", [[CBLayout]], 136, 0, 32, 64, 128))
10+
// CHECK: @c1 = external addrspace(2) global [2 x float], align 4
11+
// CHECK: @c2 = external addrspace(2) global [2 x <4 x i32>], align 16
12+
// CHECK: @c3 = external addrspace(2) global [2 x [2 x i32]], align 4
13+
// CHECK: @c4 = external addrspace(2) global [1 x target("dx.Layout", %S, 8, 0, 4)], align 4
14+
15+
cbuffer CBArrays {
16+
float c1[2];
17+
int4 c2[2];
18+
int c3[2][2];
19+
S c4[1];
20+
}
221

322
// CHECK-LABEL: define void {{.*}}arr_assign1
423
// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
@@ -116,3 +135,45 @@ void arr_assign7() {
116135
int Arr2[2][2] = {{0, 0}, {1, 1}};
117136
(Arr = Arr2)[0] = {6, 6};
118137
}
138+
139+
// Verify you can assign from a cbuffer array
140+
141+
// CHECK-LABEL: define void {{.*}}arr_assign8
142+
// CHECK: [[C:%.*]] = alloca [2 x float], align 4
143+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 8, i1 false)
144+
// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c1, i32 8, i1 false)
145+
// CHECK-NEXT: ret void
146+
void arr_assign8() {
147+
float C[2] = {1.0, 2.0};
148+
C = c1;
149+
}
150+
151+
// CHECK-LABEL: define void {{.*}}arr_assign9
152+
// CHECK: [[C:%.*]] = alloca [2 x <4 x i32>], align 16
153+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[C]], ptr align 16 {{.*}}, i32 32, i1 false)
154+
// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 16 [[C]], ptr addrspace(2) align 16 @c2, i32 32, i1 false)
155+
// CHECK-NEXT: ret void
156+
void arr_assign9() {
157+
int4 C[2] = {1,2,3,4,5,6,7,8};
158+
C = c2;
159+
}
160+
161+
// CHECK-LABEL: define void {{.*}}arr_assign10
162+
// CHECK: [[C:%.*]] = alloca [2 x [2 x i32]], align 4
163+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 16, i1 false)
164+
// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c3, i32 16, i1 false)
165+
// CHECK-NEXT: ret void
166+
void arr_assign10() {
167+
int C[2][2] = {1,2,3,4};
168+
C = c3;
169+
}
170+
171+
// CHECK-LABEL: define void {{.*}}arr_assign11
172+
// CHECK: [[C:%.*]] = alloca [1 x %struct.S], align 4
173+
// CHECK: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c4, i32 8, i1 false)
174+
// CHECK-NEXT: ret void
175+
void arr_assign11() {
176+
S s = {1, 2.0};
177+
S C[1] = {s};
178+
C = c4;
179+
}

0 commit comments

Comments
 (0)