https://github.com/amanmaurya92 updated https://github.com/llvm/llvm-project/pull/227316
>From ea039e4cd2cf5325e1612956de8aba63ef93ab8a Mon Sep 17 00:00:00 2001 From: amanmaurya92 <[email protected]> Date: Tue, 29 Sep 2026 19:16:28 +0530 Subject: [PATCH 1/2] [CIR] Support CXXThisExpr in emitLValue Support `CXXThisExpr` in `CIRGenFunction::emitLValue` by wrapping `loadCXXThisAddress()` into an LValue via `makeAddrLValue()`, matching classic Clang codegen (`CGExpr.cpp:1865`). This enables LValue contexts for `this`, such as member access expressions via `this.field` in languages like HLSL where `this` is reference-like. Fixes #227193 --- clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 3 +- .../test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 clang/test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index 823ccbe1d2e82..ca4cf4be63de3 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -1301,8 +1301,7 @@ LValue CIRGenFunction::emitLValue(const Expr *e) { "emitLValue: MatrixElementExpr"); return LValue(); case Expr::CXXThisExprClass: - getCIRGenModule().errorNYI(e->getSourceRange(), "emitLValue: CXXThisExpr"); - return LValue(); + return makeAddrLValue(loadCXXThisAddress(), e->getType()); case Expr::MemberExprClass: return emitMemberExpr(cast<MemberExpr>(e)); case Expr::CompoundLiteralExprClass: diff --git a/clang/test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl b/clang/test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl new file mode 100644 index 0000000000000..d1bc47215804b --- /dev/null +++ b/clang/test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -x hlsl -triple spirv-unknown-vulkan-library -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -x hlsl -triple spirv-unknown-vulkan-library -fclangir -emit-llvm %s -o %t.cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.cir.ll %s +// RUN: %clang_cc1 -x hlsl -triple spirv-unknown-vulkan-library -emit-llvm -disable-llvm-passes %s -o %t.ll +// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s + +struct S { + int a; + + int getA() { + return this.a; + } + + void setA(int v) { + this.a = v; + } +}; + +export int testGet() { + S s; + return s.getA(); +} + +// CIR-LABEL: cir.func {{.*}} @_ZN1S4getAEv +// CIR: %[[THIS_ADDR:.*]] = cir.alloca "this" {{.*}} : !cir.ptr<!cir.ptr<!rec_S>> +// CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S> +// CIR: %[[MEMBER:.*]] = cir.get_member %[[THIS]][0] {name = "a"} : !cir.ptr<!rec_S> -> !cir.ptr<!s32i> +// CIR: %[[VAL:.*]] = cir.load {{.*}} %[[MEMBER]] : !cir.ptr<!s32i>, !s32i +// CIR: cir.store %[[VAL]], %[[RETVAL:.*]] : !s32i, !cir.ptr<!s32i> +// CIR: cir.return {{.*}} : !s32i + +// LLVM-LABEL: define {{.*}} @_ZN1S4getAEv( +// LLVM-SAME: ptr {{.*}} %[[ARG0:.*]]) +// LLVM: %[[THIS_ADDR:.*]] = alloca ptr +// LLVM: store ptr %[[ARG0]], ptr %[[THIS_ADDR]] +// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]] +// LLVM: %[[GEP:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[THIS]], i32 0, i32 0 +// LLVM: %[[VAL:.*]] = load i32, ptr %[[GEP]] +// LLVM: ret i32 %{{.*}} + +// OGCG-LABEL: define {{.*}} @_ZN1S4getAEv( +// OGCG-SAME: ptr {{.*}} %[[ARG0:.*]]) +// OGCG: %[[THIS_ADDR:.*]] = alloca ptr +// OGCG: store ptr %[[ARG0]], ptr %[[THIS_ADDR]] +// OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]] +// OGCG: %[[GEP:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[THIS]], i32 0, i32 0 +// OGCG: %[[VAL:.*]] = load i32, ptr %[[GEP]] +// OGCG: ret i32 %[[VAL]] + +export void testSet(int v) { + S s; + s.setA(v); +} + +// CIR-LABEL: cir.func {{.*}} @_ZN1S4setAEi +// CIR: %[[THIS_ADDR:.*]] = cir.alloca "this" {{.*}} : !cir.ptr<!cir.ptr<!rec_S>> +// CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S> +// CIR: %[[MEMBER:.*]] = cir.get_member %[[THIS]][0] {name = "a"} : !cir.ptr<!rec_S> -> !cir.ptr<!s32i> +// CIR: cir.store align(1) {{.*}}, %[[MEMBER]] : !s32i, !cir.ptr<!s32i> +// CIR: cir.return + +// LLVM-LABEL: define {{.*}} @_ZN1S4setAEi( +// LLVM-SAME: ptr {{.*}} %[[ARG0:.*]], i32 {{.*}} %[[ARG1:.*]]) +// LLVM: %[[THIS_ADDR:.*]] = alloca ptr +// LLVM: store ptr %[[ARG0]], ptr %[[THIS_ADDR]] +// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]] +// LLVM: %[[GEP:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[THIS]], i32 0, i32 0 +// LLVM: store i32 {{.*}}, ptr %[[GEP]] +// LLVM: ret void + +// OGCG-LABEL: define {{.*}} @_ZN1S4setAEi( +// OGCG-SAME: ptr {{.*}} %[[ARG0:.*]], i32 {{.*}} %[[ARG1:.*]]) +// OGCG: %[[THIS_ADDR:.*]] = alloca ptr +// OGCG: store ptr %[[ARG0]], ptr %[[THIS_ADDR]] +// OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]] +// OGCG: %[[GEP:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[THIS]], i32 0, i32 0 +// OGCG: store i32 {{.*}}, ptr %[[GEP]] +// OGCG: ret void >From 9543e873e93cc42608c6b2a9e1c92273326cf734 Mon Sep 17 00:00:00 2001 From: amanmaurya92 <[email protected]> Date: Tue, 29 Sep 2026 20:02:04 +0530 Subject: [PATCH 2/2] [CIR][test] Unify LLVM and OGCG check prefixes in cxx-this-lvalue.hlsl Unify LLVM IR check prefixes for CIR-to-LLVM and classic Clang OGCG runs in cxx-this-lvalue.hlsl and drop redundant duplicate check lines, addressing review feedback. --- .../test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/clang/test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl b/clang/test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl index d1bc47215804b..c841e64de95f6 100644 --- a/clang/test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl +++ b/clang/test/CIR/CodeGenHLSL/cxx-this-lvalue.hlsl @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -x hlsl -triple spirv-unknown-vulkan-library -fclangir -emit-llvm %s -o %t.cir.ll // RUN: FileCheck --check-prefix=LLVM --input-file=%t.cir.ll %s // RUN: %clang_cc1 -x hlsl -triple spirv-unknown-vulkan-library -emit-llvm -disable-llvm-passes %s -o %t.ll -// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s struct S { int a; @@ -39,15 +39,6 @@ export int testGet() { // LLVM: %[[VAL:.*]] = load i32, ptr %[[GEP]] // LLVM: ret i32 %{{.*}} -// OGCG-LABEL: define {{.*}} @_ZN1S4getAEv( -// OGCG-SAME: ptr {{.*}} %[[ARG0:.*]]) -// OGCG: %[[THIS_ADDR:.*]] = alloca ptr -// OGCG: store ptr %[[ARG0]], ptr %[[THIS_ADDR]] -// OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]] -// OGCG: %[[GEP:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[THIS]], i32 0, i32 0 -// OGCG: %[[VAL:.*]] = load i32, ptr %[[GEP]] -// OGCG: ret i32 %[[VAL]] - export void testSet(int v) { S s; s.setA(v); @@ -68,12 +59,3 @@ export void testSet(int v) { // LLVM: %[[GEP:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[THIS]], i32 0, i32 0 // LLVM: store i32 {{.*}}, ptr %[[GEP]] // LLVM: ret void - -// OGCG-LABEL: define {{.*}} @_ZN1S4setAEi( -// OGCG-SAME: ptr {{.*}} %[[ARG0:.*]], i32 {{.*}} %[[ARG1:.*]]) -// OGCG: %[[THIS_ADDR:.*]] = alloca ptr -// OGCG: store ptr %[[ARG0]], ptr %[[THIS_ADDR]] -// OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]] -// OGCG: %[[GEP:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[THIS]], i32 0, i32 0 -// OGCG: store i32 {{.*}}, ptr %[[GEP]] -// OGCG: ret void _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
