https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/135493
This change adds an ArraySubscriptExpr from the function parameter with base type as Pointer Issue https://github.com/llvm/llvm-project/issues/130197 >From 650a2402bef4ef83abaaa2b5ae78a7bcdfb4b79f Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Fri, 11 Apr 2025 23:39:10 +0200 Subject: [PATCH] [CIR] Upstream ArraySubscriptExpr for base type as pointer --- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 14 +++- clang/test/CIR/CodeGen/array.cpp | 95 ++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 17 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index f0732a8ea60af..5179f732a4aa2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -570,9 +570,17 @@ CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) { } // The base must be a pointer; emit it with an estimate of its alignment. - cgm.errorNYI(e->getSourceRange(), - "emitArraySubscriptExpr: The base must be a pointer"); - return {}; + assert(e->getBase()->getType()->isPointerType() && + "The base must be a pointer"); + + LValueBaseInfo eltBaseInfo; + const Address ptrAddr = emitPointerWithAlignment(e->getBase(), &eltBaseInfo); + // Propagate the alignment from the array itself to the result. + const Address addxr = emitArraySubscriptPtr( + *this, cgm.getLoc(e->getBeginLoc()), cgm.getLoc(e->getEndLoc()), ptrAddr, + e->getType(), idx, cgm.getLoc(e->getExprLoc()), + /*shouldDecay=*/false); + return LValue::makeAddr(addxr, e->getType(), eltBaseInfo); } LValue CIRGenFunction::emitBinaryOperatorLValue(const BinaryOperator *e) { diff --git a/clang/test/CIR/CodeGen/array.cpp b/clang/test/CIR/CodeGen/array.cpp index 5cda061cdbf12..f63ff79db59ae 100644 --- a/clang/test/CIR/CodeGen/array.cpp +++ b/clang/test/CIR/CodeGen/array.cpp @@ -350,20 +350,87 @@ void func7() { // OGCG: %[[ARR:.*]] = alloca [1 x ptr], align 8 // OGCG: call void @llvm.memset.p0.i64(ptr align 8 %[[ARR]], i8 0, i64 8, i1 false) -void func8(int p[10]) {} -// CIR: cir.func @func8(%arg0: !cir.ptr<!s32i> -// CIR: cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["p", init] - -// LLVM: define void @func8(ptr {{%.*}}) -// LLVM-NEXT: alloca ptr, i64 1, align 8 - -// OGCG: alloca ptr, align 8 +void func8(int arr[10]) { + int e = arr[0]; + int e2 = arr[1]; +} -void func9(int pp[10][5]) {} -// CIR: cir.func @func9(%arg0: !cir.ptr<!cir.array<!s32i x 5>> -// CIR: cir.alloca !cir.ptr<!cir.array<!s32i x 5>>, !cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>> +// CIR: cir.func @func8(%[[ARG:.*]]: !cir.ptr<!s32i> +// CIR: %[[ARR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arr", init] +// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init] +// CIR: %[[INIT_2:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e2", init] +// CIR: cir.store %[[ARG]], %[[ARR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>> +// CIR: %[[IDX:.*]] = cir.const #cir.int<0> : !s32i +// CIR: %[[TMP_1:.*]] = cir.load %[[ARR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i> +// CIR: %[[ELE_0:.*]] = cir.ptr_stride(%[[TMP_1]] : !cir.ptr<!s32i>, %[[IDX]] : !s32i), !cir.ptr<!s32i> +// CIR: %[[TMP_2:.*]] = cir.load %[[ELE_0]] : !cir.ptr<!s32i>, !s32i +// CIR: cir.store %[[TMP_2]], %[[INIT]] : !s32i, !cir.ptr<!s32i> +// CIR: %[[IDX_1:.*]] = cir.const #cir.int<1> : !s32i +// CIR: %[[TMP_3:.*]] = cir.load %[[ARR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i> +// CIR: %[[ELE_1:.*]] = cir.ptr_stride(%[[TMP_3]] : !cir.ptr<!s32i>, %[[IDX_1]] : !s32i), !cir.ptr<!s32i> +// CIR: %[[TMP_4:.*]] = cir.load %[[ELE_1]] : !cir.ptr<!s32i>, !s32i +// CIR: cir.store %[[TMP_4]], %[[INIT_2]] : !s32i, !cir.ptr<!s32i> + +// LLVM: define void @func8(ptr %[[ARG:.*]]) +// LLVM: %[[ARR:.*]] = alloca ptr, i64 1, align 8 +// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[INIT_2:.*]] = alloca i32, i64 1, align 4 +// LLVM: store ptr %[[ARG]], ptr %[[ARR]], align 8 +// LLVM: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8 +// LLVM: %[[ELE_0:.*]] = getelementptr i32, ptr %[[TMP_1]], i64 0 +// LLVM: %[[TMP_2:.*]] = load i32, ptr %[[ELE_0]], align 4 +// LLVM: store i32 %[[TMP_2]], ptr %[[INIT]], align 4 +// LLVM: %[[TMP_3:.*]] = load ptr, ptr %[[ARR]], align 8 +// LLVM: %[[ELE_1:.*]] = getelementptr i32, ptr %[[TMP_3]], i64 1 +// LLVM: %[[TMP_4:.*]] = load i32, ptr %[[ELE_1]], align 4 +// LLVM: store i32 %[[TMP_4]], ptr %[[INIT_2]], align 4 + +// OGCG: %[[ARR:.*]] = alloca ptr, align 8 +// OGCG: %[[INIT:.*]] = alloca i32, align 4 +// OGCG: %[[INIT_2:.*]] = alloca i32, align 4 +// OGCG: store ptr {{%.*}}, ptr %[[ARR]], align 8 +// OGCG: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8 +// OGCG: %[[ELE_0:.*]] = getelementptr inbounds i32, ptr %[[TMP_1]], i64 0 +// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[ELE_0]], align 4 +// OGCG: store i32 %[[TMP_2]], ptr %[[INIT]], align 4 +// OGCG: %[[TMP_3:.*]] = load ptr, ptr %[[ARR]], align 8 +// OGCG: %[[ELE_1:.*]] = getelementptr inbounds i32, ptr %[[TMP_3]], i64 1 +// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[ELE_1]], align 4 +// OGCG: store i32 %[[TMP_2]], ptr %[[INIT_2]], align 4 -// LLVM: define void @func9(ptr {{%.*}}) -// LLVM-NEXT: alloca ptr, i64 1, align 8 +void func9(int arr[10][5]) { + int e = arr[1][2]; +} -// OGCG: alloca ptr, align 8 +// CIR: cir.func @func9(%[[ARG:.*]]: !cir.ptr<!cir.array<!s32i x 5>> +// CIR: %[[ARR:.*]] = cir.alloca !cir.ptr<!cir.array<!s32i x 5>>, !cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>>, ["arr", init] +// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init] +// CIR: cir.store %[[ARG]], %[[ARR]] : !cir.ptr<!cir.array<!s32i x 5>>, !cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>> +// CIR: %[[IDX:.*]] = cir.const #cir.int<2> : !s32i +// CIR: %[[IDX_1:.*]] = cir.const #cir.int<1> : !s32i +// CIR: %[[TMP_1:.*]] = cir.load %[[ARR]] : !cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>>, !cir.ptr<!cir.array<!s32i x 5>> +// CIR: %[[ARR_1:.*]] = cir.ptr_stride(%[[TMP_1]] : !cir.ptr<!cir.array<!s32i x 5>>, %[[IDX_1]] : !s32i), !cir.ptr<!cir.array<!s32i x 5>> +// CIR: %[[ARR_1_PTR:.*]] = cir.cast(array_to_ptrdecay, %[[ARR_1]] : !cir.ptr<!cir.array<!s32i x 5>>), !cir.ptr<!s32i> +// CIR: %[[ARR_1_2:.*]] = cir.ptr_stride(%[[ARR_1_PTR]] : !cir.ptr<!s32i>, %[[IDX]] : !s32i), !cir.ptr<!s32i> +// CIR: %[[TMP_2:.*]] = cir.load %[[ARR_1_2]] : !cir.ptr<!s32i>, !s32i +// CIR: cir.store %[[TMP_2]], %[[INIT]] : !s32i, !cir.ptr<!s32i> + +// LLVM: define void @func9(ptr %[[ARG:.*]]) +// LLVM: %[[ARR:.*]] = alloca ptr, i64 1, align 8 +// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4 +// LLVM: store ptr %[[ARG]], ptr %[[ARR]], align 8 +// LLVM: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8 +// LLVM: %[[ARR_1:.*]] = getelementptr [5 x i32], ptr %[[TMP_1]], i64 1 +// LLVM: %[[ARR_1_PTR:.*]] = getelementptr i32, ptr %[[ARR_1]], i32 0 +// LLVM: %[[ARR_1_2:.*]] = getelementptr i32, ptr %[[ARR_1_PTR]], i64 2 +// LLVM: %[[TMP_2:.*]] = load i32, ptr %[[ARR_1_2]], align 4 +// LLVM: store i32 %[[TMP_2]], ptr %[[INIT]], align 4 + +// OGCG: %[[ARR:.*]] = alloca ptr, align 8 +// OGCG: %[[INIT:.*]] = alloca i32, align 4 +// OGCG: store ptr {{%.*}}, ptr %[[ARR]], align 8 +// OGCG: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8 +// OGCG: %[[ARR_1:.*]] = getelementptr inbounds [5 x i32], ptr %[[TMP_1]], i64 1 +// OGCG: %[[ARR_1_2:.*]] = getelementptr inbounds [5 x i32], ptr %[[ARR_1]], i64 0, i64 2 +// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[ARR_1_2]], align 4 +// OGCG: store i32 %[[TMP_2]], ptr %[[INIT]], align 4 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits