[clang] f408506 - [CIR] Support PackIndexingExpr for LValue and Aggregates (#227040)

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 28 20:56:21 PDT 2026


Author: Aman Maurya
Date: 2026-09-29T09:26:15+05:30
New Revision: f4085066128ac709f25c206c9701285f60a0bf83

URL: https://github.com/llvm/llvm-project/commit/f4085066128ac709f25c206c9701285f60a0bf83
DIFF: https://github.com/llvm/llvm-project/commit/f4085066128ac709f25c206c9701285f60a0bf83.diff

LOG: [CIR] Support PackIndexingExpr for LValue and Aggregates (#227040)

Support `PackIndexingExpr` in `CIRGenFunction::emitLValue` and
`AggExprEmitter` by visiting its selected expression, matching classic
Clang codegen (`CGExpr.cpp` and `CGExprAgg.cpp`) and completing
`PackIndexingExpr` support across all CIR expression emitters.

Fixes #226928

Assisted by Antigravity and Gemini

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
    clang/lib/CIR/CodeGen/CIRGenFunction.cpp
    clang/test/CIR/CodeGen/pack-indexing.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 9cdb57a80deb2..562002424a16f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -18,6 +18,7 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/CodeGenUtils/ExprUtils.h"
@@ -335,6 +336,9 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
   void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e) {
     Visit(e->getReplacement());
   }
+  void VisitPackIndexingExpr(PackIndexingExpr *e) {
+    Visit(e->getSelectedExpr());
+  }
   void VisitConstantExpr(ConstantExpr *e) {
     ensureDest(cgf.getLoc(e->getSourceRange()), e->getType());
 

diff  --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 333610196c796..823ccbe1d2e82 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -1341,9 +1341,7 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
     getCIRGenModule().errorNYI(e->getSourceRange(), "emitLValue: CoyieldExpr");
     return LValue();
   case Expr::PackIndexingExprClass:
-    getCIRGenModule().errorNYI(e->getSourceRange(),
-                               "emitLValue: PackIndexingExpr");
-    return LValue();
+    return emitLValue(cast<PackIndexingExpr>(e)->getSelectedExpr());
   case Expr::HLSLOutArgExprClass:
     llvm_unreachable("cannot emit a HLSL out argument directly");
   }

diff  --git a/clang/test/CIR/CodeGen/pack-indexing.cpp b/clang/test/CIR/CodeGen/pack-indexing.cpp
index 389760655704e..86b63c004f06f 100644
--- a/clang/test/CIR/CodeGen/pack-indexing.cpp
+++ b/clang/test/CIR/CodeGen/pack-indexing.cpp
@@ -128,3 +128,93 @@ float _Complex pack_indexing_complex() {
 // OGCG:   store float %[[RESULT_IMAG]], ptr %[[RET_IMAG_PTR]], align 4
 // OGCG:   %[[TMP_RET:.*]] = load <2 x float>, ptr %[[RET_VAL]], align 4
 // OGCG:   ret <2 x float> %[[TMP_RET]]
+
+template <typename... T>
+auto &pack_indexing_lvalue_helper(T &...p) {
+  return p...[0];
+}
+
+void pack_indexing_lvalue() {
+  int a = 1;
+  int &ref = pack_indexing_lvalue_helper(a);
+}
+
+// CIR: cir.func {{.*}} @_Z20pack_indexing_lvaluev()
+// CIR:   %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!s32i>
+// CIR:   %[[REF_ADDR:.*]] = cir.alloca "ref" {{.*}} : !cir.ptr<!cir.ptr<!s32i>>
+// CIR:   %[[CALL_RES:.*]] = cir.call @_Z27pack_indexing_lvalue_helperIJiEERDaDpRT_(%[[A_ADDR]])
+// CIR:   cir.store{{.*}} %[[CALL_RES]], %[[REF_ADDR]]
+// CIR:   cir.return
+
+// CIR: cir.func {{.*}} @_Z27pack_indexing_lvalue_helperIJiEERDaDpRT_(%[[ARG0:.*]]: !cir.ptr<!s32i> {{.*}}) -> (!cir.ptr<!s32i> {{.*}})
+// CIR:   %[[P_ADDR:.*]] = cir.alloca "p" {{.*}} : !cir.ptr<!cir.ptr<!s32i>>
+// CIR:   %[[RET_VAL:.*]] = cir.alloca "__retval" {{.*}} : !cir.ptr<!cir.ptr<!s32i>>
+// CIR:   cir.store %[[ARG0]], %[[P_ADDR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
+// CIR:   %[[P_LOAD:.*]] = cir.load %[[P_ADDR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
+// CIR:   cir.store %[[P_LOAD]], %[[RET_VAL]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
+// CIR:   %[[RET_LOAD:.*]] = cir.load %[[RET_VAL]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
+// CIR:   cir.return %[[RET_LOAD]] : !cir.ptr<!s32i>
+
+// LLVM: define {{.*}} void @_Z20pack_indexing_lvaluev()
+// LLVM:   %[[A_ADDR:.*]] = alloca i32, align 4
+// LLVM:   %[[REF_ADDR:.*]] = alloca ptr, align 8
+// LLVM:   store i32 1, ptr %[[A_ADDR]], align 4
+// LLVM:   %[[CALL_RES:.*]] = call {{.*}} ptr @_Z27pack_indexing_lvalue_helperIJiEERDaDpRT_(ptr {{.*}} %[[A_ADDR]])
+// LLVM:   store ptr %[[CALL_RES]], ptr %[[REF_ADDR]], align 8
+// LLVM:   ret void
+
+// LLVM: define {{.*}} ptr @_Z27pack_indexing_lvalue_helperIJiEERDaDpRT_(ptr {{.*}} %[[ARG0:.*]])
+// LLVM:   %[[P_ADDR:.*]] = alloca ptr, align 8
+// LLVM:   %[[RET_VAL:.*]] = alloca ptr, align 8
+// LLVM:   store ptr %[[ARG0]], ptr %[[P_ADDR]], align 8
+// LLVM:   %[[P_LOAD:.*]] = load ptr, ptr %[[P_ADDR]], align 8
+// LLVM:   store ptr %[[P_LOAD]], ptr %[[RET_VAL]], align 8
+// LLVM:   %[[RET_LOAD:.*]] = load ptr, ptr %[[RET_VAL]], align 8
+// LLVM:   ret ptr %[[RET_LOAD]]
+
+// OGCG: define {{.*}} void @_Z20pack_indexing_lvaluev()
+// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
+// OGCG:   %[[REF_ADDR:.*]] = alloca ptr, align 8
+// OGCG:   store i32 1, ptr %[[A_ADDR]], align 4
+// OGCG:   %[[CALL_RES:.*]] = call {{.*}} ptr @_Z27pack_indexing_lvalue_helperIJiEERDaDpRT_(ptr {{.*}} %[[A_ADDR]])
+// OGCG:   store ptr %[[CALL_RES]], ptr %[[REF_ADDR]], align 8
+// OGCG:   ret void
+
+// OGCG: define {{.*}} ptr @_Z27pack_indexing_lvalue_helperIJiEERDaDpRT_(ptr {{.*}} %[[ARG0:.*]])
+// OGCG:   %[[P_ADDR:.*]] = alloca ptr, align 8
+// OGCG:   store ptr %[[ARG0]], ptr %[[P_ADDR]], align 8
+// OGCG:   %[[LOAD:.*]] = load ptr, ptr %[[P_ADDR]], align 8
+// OGCG:   ret ptr %[[LOAD]]
+
+struct Agg {
+  int a;
+  int b;
+};
+
+Agg pack_indexing_aggregate() {
+  return pack_indexing(Agg{1, 2}, Agg{3, 4});
+}
+
+// CIR: cir.func {{.*}} @_Z23pack_indexing_aggregatev()
+// CIR:   %[[AGG0:.*]] = cir.alloca "agg.tmp0" {{.*}} : !cir.ptr<!rec_Agg>
+// CIR:   %[[AGG1:.*]] = cir.alloca "agg.tmp1" {{.*}} : !cir.ptr<!rec_Agg>
+// CIR:   cir.call @_Z13pack_indexingIJ3AggS0_EEDaDpT_
+
+// CIR: cir.func {{.*}} @_Z13pack_indexingIJ3AggS0_EEDaDpT_
+// CIR:   %[[P0:.*]] = cir.alloca "p" {{.*}} : !cir.ptr<!rec_Agg>
+// CIR:   %[[P1:.*]] = cir.alloca "p" {{.*}} : !cir.ptr<!rec_Agg>
+// CIR:   %[[RET_VAL:.*]] = cir.alloca "__retval" {{.*}} : !cir.ptr<!rec_Agg>
+// CIR:   cir.copy %[[P0]] {{.*}} to %[[RET_VAL]] {{.*}} : !cir.ptr<!rec_Agg>
+
+// LLVM: define {{.*}} i64 @_Z23pack_indexing_aggregatev()
+// LLVM:   call i64 @_Z13pack_indexingIJ3AggS0_EEDaDpT_
+
+// LLVM: define {{.*}} i64 @_Z13pack_indexingIJ3AggS0_EEDaDpT_
+// LLVM:   call void @llvm.memcpy.p0.p0.i64
+
+// OGCG: define {{.*}} i64 @_Z23pack_indexing_aggregatev()
+// OGCG:   call i64 @_Z13pack_indexingIJ3AggS0_EEDaDpT_
+
+// OGCG: define {{.*}} i64 @_Z13pack_indexingIJ3AggS0_EEDaDpT_
+// OGCG:   call void @llvm.memcpy.p0.p0.i64
+


        


More information about the cfe-commits mailing list