https://github.com/spall updated https://github.com/llvm/llvm-project/pull/229939
>From 83235680a7d359f216091f848c9a478d2c761906 Mon Sep 17 00:00:00 2001 From: Sarah Spall <[email protected]> Date: Wed, 7 Oct 2026 15:40:26 -0700 Subject: [PATCH 1/2] implicit struct passing for groupshared struct --- clang/lib/Sema/SemaOverload.cpp | 13 ++++---- clang/test/AST/HLSL/StructPassing-AST.hlsl | 18 +++++++++++ .../BasicFeatures/StructPassing.hlsl | 30 +++++++++++++++++++ 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index e5049d11480ac..44b397d2a47b9 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -6344,12 +6344,15 @@ ExprResult Sema::PerformImplicitObjectArgumentInitialization( QualType FromRecordType, DestType; QualType ImplicitParamRecordType = Method->getFunctionObjectParameterType(); + LangAS FromAS = From->getType().getAddressSpace(); if (getLangOpts().HLSL && - From->getType().getAddressSpace() == LangAS::hlsl_constant) { - QualType CastType = From->getType().getLocalUnqualifiedType().withConst(); - From = ImplicitCastExpr::Create(Context, CastType, CK_LValueToRValue, From, - /*BasePath=*/nullptr, VK_PRValue, - FPOptionsOverride()); + (FromAS == LangAS::hlsl_constant || FromAS == LangAS::hlsl_groupshared)) { + QualType CastType = From->getType().getLocalUnqualifiedType(); + From = ImplicitCastExpr::Create( + Context, + FromAS == LangAS::hlsl_constant ? CastType.withConst() : CastType, + CK_LValueToRValue, From, + /*BasePath=*/nullptr, VK_PRValue, FPOptionsOverride()); } Expr::Classification FromClassification; diff --git a/clang/test/AST/HLSL/StructPassing-AST.hlsl b/clang/test/AST/HLSL/StructPassing-AST.hlsl index 8ae83fa89b390..745187514bd43 100644 --- a/clang/test/AST/HLSL/StructPassing-AST.hlsl +++ b/clang/test/AST/HLSL/StructPassing-AST.hlsl @@ -118,5 +118,23 @@ void case6(S s) { useP(s); } +struct G { + void f() {} +}; + +groupshared G g; + +// CHECK: FunctionDecl {{.*}} case7 'void ()' +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: ExprWithCleanups {{.*}} 'void' +// CHECK-NEXT: CXXMemberCallExpr {{.*}} 'void' +// CHECK-NEXT: MemberExpr {{.*}} '<bound member function type>' .f {{.*}} +// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'G' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'G' <LValueToRValue> +// CHECK-NEXT: DeclRefExpr {{.*}} 'groupshared G' lvalue Var {{.*}} 'g' 'groupshared G' +void case7() { + g.f(); +} + // CHECK-NOT: CXXConstructExpr // CHECK-NOT: CXXOperatorCallExpr diff --git a/clang/test/CodeGenHLSL/BasicFeatures/StructPassing.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/StructPassing.hlsl index c80c7c9466afc..a846f682493fa 100644 --- a/clang/test/CodeGenHLSL/BasicFeatures/StructPassing.hlsl +++ b/clang/test/CodeGenHLSL/BasicFeatures/StructPassing.hlsl @@ -133,3 +133,33 @@ void case6(S s) { // derived to base conversion in argument passing useP(s); } + +// CHECK-LABEL: define hidden void @_Z5case7v( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_G:%.*]], align 1 +// CHECK-NEXT: call void @_ZN1G1fEv(ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) #[[ATTR3]] [ "convergencectrl"(token [[TMP0]]) ] +// CHECK-NEXT: ret void +// +void case7(); + +struct G { +// CHECK-LABEL: define linkonce_odr hidden void @_ZN1G1fEv( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR0]] align 2 { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 4 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 4 +// CHECK-NEXT: ret void +// + void f() {} +}; + +groupshared G g; + +void case7() { + // implicit argument passing of a groupshared struct + g.f(); +} >From 4437bff2ca71e485c76f4bdb8ebaa58aac64cbfc Mon Sep 17 00:00:00 2001 From: Sarah Spall <[email protected]> Date: Wed, 7 Oct 2026 16:47:10 -0700 Subject: [PATCH 2/2] add new test. change test file so update script won't break new tests --- .../BasicFeatures/StructPassing.hlsl | 59 +++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/clang/test/CodeGenHLSL/BasicFeatures/StructPassing.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/StructPassing.hlsl index a846f682493fa..07455027a1ac7 100644 --- a/clang/test/CodeGenHLSL/BasicFeatures/StructPassing.hlsl +++ b/clang/test/CodeGenHLSL/BasicFeatures/StructPassing.hlsl @@ -134,19 +134,33 @@ void case6(S s) { useP(s); } +// disabled otherwise the IR will be generated in the wrong order. +// UTC_ARGS: --disable + +struct G { + int X; + void f() {} + void setX(int val) { this.X = val; } +}; + +groupshared G g; + // CHECK-LABEL: define hidden void @_Z5case7v( // CHECK-SAME: ) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() // CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_G:%.*]], align 1 -// CHECK-NEXT: call void @_ZN1G1fEv(ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) #[[ATTR3]] [ "convergencectrl"(token [[TMP0]]) ] +// CHECK-NEXT: call void @llvm.memcpy.p0.p3.i32(ptr align 1 [[REF_TMP]], ptr addrspace(3) align 1 @g, i32 4, i1 false) +// CHECK-NEXT: call void @_ZN1G1fEv(ptr noundef nonnull align 1 dereferenceable(4) [[REF_TMP]]) #[[ATTR3]] [ "convergencectrl"(token [[TMP0]]) ] // CHECK-NEXT: ret void // -void case7(); +void case7() { + // implicit argument passing of a groupshared struct + g.f(); +} -struct G { // CHECK-LABEL: define linkonce_odr hidden void @_ZN1G1fEv( -// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR0]] align 2 { +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(4) [[THIS:%.*]]) #[[ATTR0]] align 2 { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 4 @@ -154,12 +168,35 @@ struct G { // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 4 // CHECK-NEXT: ret void // - void f() {} -}; - -groupshared G g; -void case7() { - // implicit argument passing of a groupshared struct - g.f(); +// CHECK-LABEL: define hidden void @_Z5case8i( +// CHECK-SAME: i32 noundef [[VAL:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_G:%.*]], align 1 +// CHECK-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p3.i32(ptr align 1 [[REF_TMP]], ptr addrspace(3) align 1 @g, i32 4, i1 false) +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[VAL_ADDR]], align 4 +// CHECK-NEXT: call void @_ZN1G4setXEi(ptr noundef nonnull align 1 dereferenceable(4) [[REF_TMP]], i32 noundef [[TMP1]]) #[[ATTR3]] [ "convergencectrl"(token [[TMP0]]) ] +// CHECK-NEXT: ret void +// +void case8(int val) { + // implicit argument passing of a groupshared struct where the implicit object is modified + g.setX(val); } + +// CHECK-LABEL: define linkonce_odr hidden void @_ZN1G4setXEi( +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(4) [[THIS:%.*]], i32 noundef [[VAL:%.*]]) #[[ATTR0]] align 2 { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 4 +// CHECK-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[VAL_ADDR]], align 4 +// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_G:%.*]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-NEXT: store i32 [[TMP1]], ptr [[X]], align 1 +// CHECK-NEXT: ret void +// _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
