https://github.com/spall updated https://github.com/llvm/llvm-project/pull/134174
>From 5d81a4b7b034dd5999feb6ab37537270d6bae2a8 Mon Sep 17 00:00:00 2001 From: Sarah Spall <sarahsp...@microsoft.com> Date: Wed, 2 Apr 2025 12:04:18 -0700 Subject: [PATCH] compare unqualified canonical types and add an hlsl array rvalue cast --- clang/lib/Sema/SemaExprCXX.cpp | 14 ++--- clang/lib/Sema/SemaOverload.cpp | 10 ++-- clang/test/CodeGenHLSL/ArrayAssignable.hlsl | 63 ++++++++++++++++++++- 3 files changed, 70 insertions(+), 17 deletions(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index fa492bc124abd..dd4887c0b2878 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4418,19 +4418,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, case ICK_HLSL_Array_RValue: if (ToType->isArrayParameterType()) { FromType = Context.getArrayParameterType(FromType); - From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue, - /*BasePath=*/nullptr, CCK) - .get(); - } else { // FromType must be ArrayParameterType - assert(FromType->isArrayParameterType() && - "FromType must be ArrayParameterType in ICK_HLSL_Array_RValue \ - if it is not ToType"); + } else if (FromType->isArrayParameterType()) { const ArrayParameterType *APT = cast<ArrayParameterType>(FromType); FromType = APT->getConstantArrayType(Context); - From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue, - /*BasePath=*/nullptr, CCK) - .get(); } + From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue, + /*BasePath=*/nullptr, CCK) + .get(); break; case ICK_Function_To_Pointer: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 1802f8f4e1f91..d282fe50e49f1 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2268,17 +2268,15 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, // handling here. if (ToType->isArrayParameterType()) { FromType = S.Context.getArrayParameterType(FromType); - SCS.First = ICK_HLSL_Array_RValue; } else if (FromType->isArrayParameterType()) { const ArrayParameterType *APT = cast<ArrayParameterType>(FromType); FromType = APT->getConstantArrayType(S.Context); - SCS.First = ICK_HLSL_Array_RValue; - } else { - SCS.First = ICK_Identity; } - if (S.Context.getCanonicalType(FromType) != - S.Context.getCanonicalType(ToType)) + SCS.First = ICK_HLSL_Array_RValue; + + if (FromType.getCanonicalType().getUnqualifiedType() != + ToType.getCanonicalType().getUnqualifiedType()) return false; SCS.setAllToTypes(ToType); diff --git a/clang/test/CodeGenHLSL/ArrayAssignable.hlsl b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl index e2ff2de68ed99..723d521596baf 100644 --- a/clang/test/CodeGenHLSL/ArrayAssignable.hlsl +++ b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl @@ -1,4 +1,23 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --enable-var-scope +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -finclude-default-header -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + +struct S { + int x; + float f; +}; + +// 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)] }> +// CHECK: @CBArrays.cb = global target("dx.CBuffer", target("dx.Layout", [[CBLayout]], 136, 0, 32, 64, 128)) +// CHECK: @c1 = external addrspace(2) global [2 x float], align 4 +// CHECK: @c2 = external addrspace(2) global [2 x <4 x i32>], align 16 +// CHECK: @c3 = external addrspace(2) global [2 x [2 x i32]], align 4 +// CHECK: @c4 = external addrspace(2) global [1 x target("dx.Layout", %S, 8, 0, 4)], align 4 + +cbuffer CBArrays { + float c1[2]; + int4 c2[2]; + int c3[2][2]; + S c4[1]; +} // CHECK-LABEL: define void {{.*}}arr_assign1 // CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4 @@ -116,3 +135,45 @@ void arr_assign7() { int Arr2[2][2] = {{0, 0}, {1, 1}}; (Arr = Arr2)[0] = {6, 6}; } + +// Verify you can assign from a cbuffer array + +// CHECK-LABEL: define void {{.*}}arr_assign8 +// CHECK: [[C:%.*]] = alloca [2 x float], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c1, i32 8, i1 false) +// CHECK-NEXT: ret void +void arr_assign8() { + float C[2] = {1.0, 2.0}; + C = c1; +} + +// CHECK-LABEL: define void {{.*}}arr_assign9 +// CHECK: [[C:%.*]] = alloca [2 x <4 x i32>], align 16 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[C]], ptr align 16 {{.*}}, i32 32, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 16 [[C]], ptr addrspace(2) align 16 @c2, i32 32, i1 false) +// CHECK-NEXT: ret void +void arr_assign9() { + int4 C[2] = {1,2,3,4,5,6,7,8}; + C = c2; +} + +// CHECK-LABEL: define void {{.*}}arr_assign10 +// CHECK: [[C:%.*]] = alloca [2 x [2 x i32]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 16, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c3, i32 16, i1 false) +// CHECK-NEXT: ret void +void arr_assign10() { + int C[2][2] = {1,2,3,4}; + C = c3; +} + +// CHECK-LABEL: define void {{.*}}arr_assign11 +// CHECK: [[C:%.*]] = alloca [1 x %struct.S], align 4 +// CHECK: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c4, i32 8, i1 false) +// CHECK-NEXT: ret void +void arr_assign11() { + S s = {1, 2.0}; + S C[1] = {s}; + C = c4; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits