https://github.com/AmrDeveloper updated 
https://github.com/llvm/llvm-project/pull/175370

>From b73eabc93fae094c2a2ef92642166aae6181ee15 Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Sat, 10 Jan 2026 17:39:01 +0100
Subject: [PATCH 1/2] [CIR] SubscriptExpr for VariableLengthArray

---
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 52 ++++++++++++++++++------
 clang/test/CIR/CodeGen/vla.c         | 60 ++++++++++++++++++++++++++--
 2 files changed, 97 insertions(+), 15 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index cd13498e3702f..0f0e9c67e9dae 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1128,12 +1128,6 @@ static Address emitArraySubscriptPtr(CIRGenFunction &cgf,
 
 LValue
 CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
-  if (getContext().getAsVariableArrayType(e->getType())) {
-    cgm.errorNYI(e->getSourceRange(),
-                 "emitArraySubscriptExpr: VariableArrayType");
-    return LValue::makeAddr(Address::invalid(), e->getType(), 
LValueBaseInfo());
-  }
-
   if (e->getType()->getAs<ObjCObjectType>()) {
     cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: 
ObjCObjectType");
     return LValue::makeAddr(Address::invalid(), e->getType(), 
LValueBaseInfo());
@@ -1165,7 +1159,14 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
                                  lv.getBaseInfo());
   }
 
-  const mlir::Value idx = emitIdxAfterBase(/*promote=*/true);
+  // The HLSL runtime handles subscript expressions on global resource arrays
+  // and objects with HLSL buffer layouts.
+  if (getLangOpts().HLSL) {
+    cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: HLSL");
+    return {};
+  }
+
+  mlir::Value idx = emitIdxAfterBase(/*promote=*/true);
 
   // Handle the extvector case we ignored above.
   if (isa<ExtVectorElementExpr>(e->getBase())) {
@@ -1181,6 +1182,36 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
     return makeAddrLValue(addr, elementType, lv.getBaseInfo());
   }
 
+  if (const VariableArrayType *vla =
+          getContext().getAsVariableArrayType(e->getType())) {
+    // The base must be a pointer, which is not an aggregate.  Emit
+    // it.  It needs to be emitted first in case it's what captures
+    // the VLA bounds.
+    Address addr = emitPointerWithAlignment(e->getBase());
+
+    // The element count here is the total number of non-VLA elements.
+    mlir::Value numElements = getVLASize(vla).numElts;
+    idx = builder.createIntCast(idx, numElements.getType());
+
+    // Effectively, the multiply by the VLA size is part of the GEP.
+    // GEP indexes are signed, and scaling an index isn't permitted to
+    // signed-overflow, so we use the same semantics for our explicit
+    // multiply.  We suppress this if overflow is not undefined behavior.
+    OverflowBehavior overflowBehavior = getLangOpts().PointerOverflowDefined
+                                            ? OverflowBehavior::None
+                                            : OverflowBehavior::NoSignedWrap;
+    idx = builder.createMul(cgm.getLoc(e->getExprLoc()), idx, numElements,
+                            overflowBehavior);
+
+    assert(!cir::MissingFeatures::emitCheckedInBoundsGEP());
+    addr = emitArraySubscriptPtr(*this, cgm.getLoc(e->getBeginLoc()),
+                                 cgm.getLoc(e->getEndLoc()), addr, 
e->getType(),
+                                 idx, cgm.getLoc(e->getExprLoc()),
+                                 /*shouldDecay=*/false);
+
+    return makeAddrLValue(addr, vla->getElementType(), LValueBaseInfo());
+  }
+
   if (const Expr *array = getSimpleArrayDecayOperand(e->getBase())) {
     LValue arrayLV;
     if (const auto *ase = dyn_cast<ArraySubscriptExpr>(array))
@@ -1738,11 +1769,8 @@ LValue CIRGenFunction::emitCompoundLiteralLValue(const 
CompoundLiteralExpr *e) {
     return {};
   }
 
-  if (e->getType()->isVariablyModifiedType()) {
-    cgm.errorNYI(e->getSourceRange(),
-                 "emitCompoundLiteralLValue: VariablyModifiedType");
-    return {};
-  }
+  if (e->getType()->isVariablyModifiedType())
+    emitVariablyModifiedType(e->getType());
 
   Address declPtr = createMemTemp(e->getType(), getLoc(e->getSourceRange()),
                                   ".compoundliteral");
diff --git a/clang/test/CIR/CodeGen/vla.c b/clang/test/CIR/CodeGen/vla.c
index 971a7def0db44..ce0cbee11add7 100644
--- a/clang/test/CIR/CodeGen/vla.c
+++ b/clang/test/CIR/CodeGen/vla.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-cir %s -o %t.cir
+// RUN: %clang_cc1 -Wno-error=incompatible-pointer-types -triple 
x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
 // RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: %clang_cc1 -Wno-error=incompatible-pointer-types -triple 
x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
 // RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-emit-llvm %s -o %t.ll
+// RUN: %clang_cc1 -Wno-error=incompatible-pointer-types -triple 
x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
 // RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
 
 void f0(int len) {
@@ -339,3 +339,57 @@ int f5(unsigned long len) {
 // OGCG:   %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]
 // OGCG:   call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])
 // OGCG:   ret i32 %[[ARR_VAL]]
+
+void vla_subscript_expr() {
+  int **a;
+  unsigned long n = 5;
+  (int (**)[n]){&a}[0][1][5] = 0;
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!cir.ptr<!cir.ptr<!s32i>>>, ["a"]
+// CIR: %[[N_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["n", init]
+// CIR: %[[COMPOUND_ADDR:.*]] = cir.alloca !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!cir.ptr<!cir.ptr<!s32i>>>, [".compoundliteral"]
+// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !u64i
+// CIR: cir.store {{.*}} %[[CONST_5]], %[[N_ADDR]] : !u64i, !cir.ptr<!u64i>
+// CIR: %[[CONST_0_VAL:.*]] = cir.const #cir.int<0> : !s32i
+// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s32i
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
+// CIR: %[[TMP_N:.*]] = cir.load {{.*}} %[[N_ADDR]] : !cir.ptr<!u64i>, !u64i
+// CIR: %[[A_VAL:.*]] = cir.cast bitcast %[[A_ADDR]] : 
!cir.ptr<!cir.ptr<!cir.ptr<!s32i>>> -> !cir.ptr<!cir.ptr<!s32i>>
+// CIR: cir.store {{.*}} %[[A_VAL]], %[[COMPOUND_ADDR]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!cir.ptr<!s32i>>>
+// CIR: %[[TMP_COMPOUND:.*]] = cir.load {{.*}} %[[COMPOUND_ADDR]] : 
!cir.ptr<!cir.ptr<!cir.ptr<!s32i>>>, !cir.ptr<!cir.ptr<!s32i>>
+// CIR: %[[COMPOUND_PTR:.*]] = cir.ptr_stride %[[TMP_COMPOUND]], %[[CONST_0]] 
: (!cir.ptr<!cir.ptr<!s32i>>, !s32i) -> !cir.ptr<!cir.ptr<!s32i>>
+// CIR: %[[TMP_COMPOUND:.*]] = cir.load {{.*}} %10 : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
+// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
+// CIR: %[[VLA_IDX:.*]] = cir.binop(mul, %[[CONST_1]], %7) nsw : !u64i
+// CIR: %[[VLA_A_PTR:.*]] = cir.ptr_stride %[[TMP_COMPOUND]], %[[VLA_IDX]] : 
(!cir.ptr<!s32i>, !u64i) -> !cir.ptr<!s32i>
+// CIR: %[[ELEM_5_PTR:.*]] = cir.ptr_stride %[[VLA_A_PTR]], %[[CONST_5]] : 
(!cir.ptr<!s32i>, !s32i) -> !cir.ptr<!s32i>
+// CIR: cir.store {{.*}} %[[CONST_0_VAL]], %[[ELEM_5_PTR]] : !s32i, 
!cir.ptr<!s32i>
+
+// LLVM: %[[A_ADDR:.*]] = alloca ptr, i64 1, align 8
+// LLVM: %[[N_ADDR:.*]] = alloca i64, i64 1, align 8
+// LLVM: %[[COMPOUND_ADDR:.*]] = alloca ptr, i64 1, align 8
+// LLVM: store i64 5, ptr %[[N_ADDR]], align 8
+// LLVM: %[[TMP_N:.*]] = load i64, ptr %[[N_ADDR]], align 8
+// LLVM: store ptr %[[A_ADDR]], ptr %[[COMPOUND_ADDR]], align 8
+// LLVM: %[[TMP_COMPOUND:.*]] = load ptr, ptr %[[COMPOUND_ADDR]], align 8
+// LLVM: %[[COMPOUND_PTR:.*]] = getelementptr ptr, ptr %[[TMP_COMPOUND]], i64 0
+// LLVM: %[[TMP_COMPOUND:.*]] = load ptr, ptr %[[COMPOUND_PTR]], align 8
+// LLVM: %[[VLA_IDX:.*]] = mul nsw i64 1, %[[TMP_N]]
+// LLVM: %[[VLA_A_PTR:.*]] = getelementptr i32, ptr %[[TMP_COMPOUND]], i64 
%[[VLA_IDX]]
+// LLVM: %[[ELEM_5_PTR:.*]] = getelementptr i32, ptr %[[VLA_A_PTR]], i64 5
+// LLVM: store i32 0, ptr %[[ELEM_5_PTR]], align 4
+
+// OGCG: %[[A_ADDR:.*]] = alloca ptr, align 8
+// OGCG: %[[N_ADDR:.*]] = alloca i64, align 8
+// OGCG: %[[COMPOUND_ADDR:.*]] = alloca ptr, align 8
+// OGCG: store i64 5, ptr %[[N_ADDR]], align 8
+// OGCG: %[[TMP_N:.*]] = load i64, ptr %[[N_ADDR]], align 8
+// OGCG: store ptr %[[A_ADDR]], ptr %[[COMPOUND_ADDR]], align 8
+// OGCG: %[[TMP_COMPOUND:.*]] = load ptr, ptr %[[COMPOUND_ADDR]], align 8
+// OGCG: %[[COMPOUND_PTR:.*]] = getelementptr inbounds ptr, ptr 
%[[TMP_COMPOUND]], i64 0
+// OGCG: %[[TMP_COMPOUND:.*]] = load ptr, ptr %[[COMPOUND_PTR]], align 8
+// OGCG: %[[VLA_IDX:.*]] = mul nsw i64 1, %[[TMP_N]]
+// OGCG: %[[VLA_A_PTR:.*]] = getelementptr inbounds i32, ptr 
%[[TMP_COMPOUND]], i64 %[[VLA_IDX]]
+// OGCG: %[[ELEM_5_PTR:.*]] = getelementptr inbounds i32, ptr %[[VLA_A_PTR]], 
i64 5
+// OGCG: store i32 0, ptr %[[ELEM_5_PTR]], align 4

>From f90cf9b4c5fa2594487d6d67046585c8210ec2e7 Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Tue, 13 Jan 2026 18:41:41 +0100
Subject: [PATCH 2/2] Remove MissingFeatures

---
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 0f0e9c67e9dae..cc97af90d823c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1203,7 +1203,6 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
     idx = builder.createMul(cgm.getLoc(e->getExprLoc()), idx, numElements,
                             overflowBehavior);
 
-    assert(!cir::MissingFeatures::emitCheckedInBoundsGEP());
     addr = emitArraySubscriptPtr(*this, cgm.getLoc(e->getBeginLoc()),
                                  cgm.getLoc(e->getEndLoc()), addr, 
e->getType(),
                                  idx, cgm.getLoc(e->getExprLoc()),

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to