[clang] 1228142 - [CIR] Implement PredefinedExpr in aggregate emitter and add consteval… (#194484)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 27 18:09:28 PDT 2026
Author: Bruno Cardoso Lopes
Date: 2026-04-27T18:09:24-07:00
New Revision: 1228142a5d6130657aaefbf22a41ed6c1482c228
URL: https://github.com/llvm/llvm-project/commit/1228142a5d6130657aaefbf22a41ed6c1482c228
DIFF: https://github.com/llvm/llvm-project/commit/1228142a5d6130657aaefbf22a41ed6c1482c228.diff
LOG: [CIR] Implement PredefinedExpr in aggregate emitter and add consteval… (#194484)
… aggregate test
Handle PredefinedExpr by delegating to emitAggLoadOfLValue, removing the
NYI fallback. Also add a test for ConstantExpr aggregate emission
(consteval functions returning structs), which was already implemented
but lacked test coverage.
This unblocks ~206 libcxx test failures that involve aggregate
ConstantExpr and PredefinedExpr.
Note on LLVM IR divergence (will be addressed in follow-up PRs): For
consteval functions returning aggregates, CIR currently emits a global
constant + cir.copy that lowers to llvm.memcpy from the global, while
OGCG decomposes the constant into per-field stores. The added CIR / LLVM
/ OGCG CHECK lines in consteval-aggregate.cpp document this difference.
Convergence will come from a follow-up that decomposes the consteval
aggregate stores into per-field stores in LoweringPrepare (and related
GEP-index handling for padded structs).
Added:
clang/test/CIR/CodeGen/consteval-aggregate.cpp
Modified:
clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
Removed:
################################################################################
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 644f1356c85e6..9c9c88c325844 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -336,10 +336,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
void VisitStringLiteral(StringLiteral *e) { emitAggLoadOfLValue(e); }
void VisitCompoundLiteralExpr(CompoundLiteralExpr *e);
- void VisitPredefinedExpr(const PredefinedExpr *e) {
- cgf.cgm.errorNYI(e->getSourceRange(),
- "AggExprEmitter: VisitPredefinedExpr");
- }
+ void VisitPredefinedExpr(const PredefinedExpr *e) { emitAggLoadOfLValue(e); }
void VisitBinaryOperator(const BinaryOperator *e) {
cgf.cgm.errorNYI(e->getSourceRange(),
"AggExprEmitter: VisitBinaryOperator");
diff --git a/clang/test/CIR/CodeGen/consteval-aggregate.cpp b/clang/test/CIR/CodeGen/consteval-aggregate.cpp
new file mode 100644
index 0000000000000..aac6ae89e88ca
--- /dev/null
+++ b/clang/test/CIR/CodeGen/consteval-aggregate.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ogcg.ll
+// RUN: FileCheck --input-file=%t.ogcg.ll %s -check-prefix=OGCG
+
+struct Agg { int a; long b; };
+consteval Agg retAgg() { return {13, 17}; }
+
+long test_retAgg() {
+ long b = retAgg().b;
+ return b;
+}
+
+// CIR-LABEL: @_Z11test_retAggv
+// CIR: cir.get_global @__const._Z11test_retAggv.ref.tmp0 : !cir.ptr<!rec_Agg>
+// CIR: cir.copy
+
+// TODO(CIR): CIR materializes consteval aggregates as global constants and
+// uses memcpy, while OGCG inlines the stores directly. This should be unified
+// to match OGCG's behavior for small aggregates.
+// LLVM-LABEL: @_Z11test_retAggv
+// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %{{.*}}, ptr @__const._Z11test_retAggv.ref.tmp0, i64 16, i1 false)
+
+// OGCG-LABEL: @_Z11test_retAggv
+// OGCG: store i32 13, ptr %{{.*}}, align 8
+// OGCG: store i64 17, ptr %{{.*}}, align 8
+
+int test_retAgg_first() {
+ int a = retAgg().a;
+ return a;
+}
+
+// CIR-LABEL: @_Z17test_retAgg_firstv
+// CIR: cir.get_global @__const._Z17test_retAgg_firstv.ref.tmp0 : !cir.ptr<!rec_Agg>
+// CIR: cir.copy
+
+// LLVM-LABEL: @_Z17test_retAgg_firstv
+// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %{{.*}}, ptr @__const._Z17test_retAgg_firstv.ref.tmp0, i64 16, i1 false)
+
+// OGCG-LABEL: @_Z17test_retAgg_firstv
+// OGCG: store i32 13, ptr %{{.*}}, align 8
+// OGCG: store i64 17, ptr %{{.*}}, align 8
More information about the cfe-commits
mailing list