Skip to content

Commit 67e56c1

Browse files
committed
[CIR] CountOf VLA with Array element type
1 parent 3564791 commit 67e56c1

File tree

2 files changed

+49
-8
lines changed

2 files changed

+49
-8
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,14 +2325,27 @@ mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
23252325
const QualType typeToSize = e->getTypeOfArgument();
23262326
const mlir::Location loc = cgf.getLoc(e->getSourceRange());
23272327
if (auto kind = e->getKind();
2328-
kind == UETT_SizeOf || kind == UETT_DataSizeOf) {
2329-
if (cgf.getContext().getAsVariableArrayType(typeToSize)) {
2330-
cgf.getCIRGenModule().errorNYI(e->getSourceRange(),
2331-
"sizeof operator for VariableArrayType",
2332-
e->getStmtClassName());
2333-
return builder.getConstant(
2334-
loc, cir::IntAttr::get(cgf.cgm.uInt64Ty,
2335-
llvm::APSInt(llvm::APInt(64, 1), true)));
2328+
kind == UETT_SizeOf || kind == UETT_DataSizeOf || kind == UETT_CountOf) {
2329+
if (const VariableArrayType *vat =
2330+
cgf.getContext().getAsVariableArrayType(typeToSize)) {
2331+
// For _Countof, we only want to evaluate if the extent is actually
2332+
// variable as opposed to a multi-dimensional array whose extent is
2333+
// constant but whose element type is variable.
2334+
bool evaluateExtent = true;
2335+
if (kind == UETT_CountOf && vat->getElementType()->isArrayType()) {
2336+
evaluateExtent =
2337+
!vat->getSizeExpr()->isIntegerConstantExpr(cgf.getContext());
2338+
}
2339+
2340+
if (evaluateExtent) {
2341+
cgf.getCIRGenModule().errorNYI(
2342+
e->getSourceRange(),
2343+
"sizeof operator for VariableArrayType & evaluateExtent",
2344+
e->getStmtClassName());
2345+
return builder.getConstant(
2346+
loc, cir::IntAttr::get(cgf.cgm.uInt64Ty,
2347+
-llvm::APSInt(llvm::APInt(64, 1), true)));
2348+
}
23362349
}
23372350
} else if (e->getKind() == UETT_OpenMPRequiredSimdAlign) {
23382351
cgf.getCIRGenModule().errorNYI(

clang/test/CIR/CodeGen/count-of.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 -std=c2y -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -std=c2y -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -std=c2y -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
7+
8+
unsigned long vla_with_array_element_type() {
9+
long size;
10+
#define int_arr int[5]
11+
return _Countof(int_arr[size]);
12+
}
13+
14+
// CIR: %[[RET_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["__retval"]
15+
// CIR: %[[SIZE_ADDR:.*]] = cir.alloca !s64i, !cir.ptr<!s64i>, ["size"]
16+
// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !u64i
17+
// CIR: cir.store %[[CONST_5]], %[[RET_ADDR]] : !u64i, !cir.ptr<!u64i>
18+
// CIR: %[[RET_VAL:.*]] = cir.load %[[RET_ADDR]] : !cir.ptr<!u64i>, !u64i
19+
// CIR: cir.return %[[RET_VAL]] : !u64i
20+
21+
// LLVM: %[[RET_ADDR:.*]] = alloca i64, i64 1, align 8
22+
// LLVM: %[[SIZE_ADDR:.*]] = alloca i64, i64 1, align 8
23+
// LLVM: store i64 5, ptr %[[RET_ADDR]], align 8
24+
// LLVM: %[[RET_VAL:.*]] = load i64, ptr %[[RET_ADDR]], align 8
25+
// LLVM: ret i64 %[[RET_VAL]]
26+
27+
// OGCG: %[[SIZE_ADDR:.*]] = alloca i64, align 8
28+
// OGCG: ret i64 5

0 commit comments

Comments
 (0)