Skip to content

Commit

Permalink
[CIR][CIRGen] Support check for zero-init pointers (#441)
Browse files Browse the repository at this point in the history
  • Loading branch information
YazZz1k authored and lanza committed Nov 2, 2024
1 parent 4e63ef1 commit 436d728
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 5 deletions.
4 changes: 3 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,9 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {

mlir::cir::ConstantOp getZero(mlir::Location loc, mlir::Type ty) {
// TODO: dispatch creation for primitive types.
assert(ty.isa<mlir::cir::StructType>() && "NYI for other types");
assert(
(ty.isa<mlir::cir::StructType>() || ty.isa<mlir::cir::ArrayType>()) &&
"NYI for other types");
return create<mlir::cir::ConstantOp>(loc, ty, getZeroAttr(ty));
}

Expand Down
7 changes: 3 additions & 4 deletions clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,10 +649,9 @@ static bool isSimpleZero(const Expr *E, CIRGenFunction &CGF) {
return true;
// (int*)0 - Null pointer expressions.
if (const CastExpr *ICE = dyn_cast<CastExpr>(E)) {
llvm_unreachable("NYI");
// return ICE->getCastKind() == CK_NullToPointer &&
// CGF.getTypes().isPointerZeroInitializable(E->getType()) &&
// !E->HasSideEffects(CGF.getContext());
return ICE->getCastKind() == CK_NullToPointer &&
CGF.getTypes().isPointerZeroInitializable(E->getType()) &&
!E->HasSideEffects(CGF.getContext());
}
// '\0'
if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E))
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,11 @@ CIRGenTypes::getCIRGenRecordLayout(const RecordDecl *RD) {
return *I->second;
}

bool CIRGenTypes::isPointerZeroInitializable(clang::QualType T) {
assert((T->isAnyPointerType() || T->isBlockPointerType()) && "Invalid type");
return isZeroInitializable(T);
}

bool CIRGenTypes::isZeroInitializable(QualType T) {
if (T->getAs<PointerType>())
return Context.getTargetNullPointerValue(T) == 0;
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ class CIRGenTypes {
/// Return whether a type can be zero-initialized (in the C++ sense) with an
/// LLVM zeroinitializer.
bool isZeroInitializable(clang::QualType T);

/// Check if the pointer type can be zero-initialized (in the C++ sense)
/// with an LLVM zeroinitializer.
bool isPointerZeroInitializable(clang::QualType T);

/// Return whether a record type can be zero-initialized (in the C++ sense)
/// with an LLVM zeroinitializer.
bool isZeroInitializable(const clang::RecordDecl *RD);
Expand Down
26 changes: 26 additions & 0 deletions clang/test/CIR/CodeGen/array-init.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o - | FileCheck %s

typedef struct {
int a;
long b;
} T;

void buz(int x) {
T arr[] = { {0, x}, {0, 0} };
}
// CHECK: cir.func @buz
// CHECK-NEXT: [[X_ALLOCA:%.*]] = cir.alloca !s32i, cir.ptr <!s32i>, ["x", init] {alignment = 4 : i64}
// CHECK-NEXT: [[ARR:%.*]] = cir.alloca !cir.array<!ty_22T22 x 2>, cir.ptr <!cir.array<!ty_22T22 x 2>>, ["arr", init] {alignment = 16 : i64}
// CHECK-NEXT: cir.store %arg0, [[X_ALLOCA]] : !s32i, cir.ptr <!s32i>
// CHECK-NEXT: [[ARR_INIT:%.*]] = cir.const(#cir.zero : !cir.array<!ty_22T22 x 2>) : !cir.array<!ty_22T22 x 2>
// CHECK-NEXT: cir.store [[ARR_INIT]], [[ARR]] : !cir.array<!ty_22T22 x 2>, cir.ptr <!cir.array<!ty_22T22 x 2>>
// CHECK-NEXT: [[FI_EL:%.*]] = cir.cast(array_to_ptrdecay, [[ARR]] : !cir.ptr<!cir.array<!ty_22T22 x 2>>), !cir.ptr<!ty_22T22>
// CHECK-NEXT: [[A_STORAGE0:%.*]] = cir.get_member [[FI_EL]][0] {name = "a"} : !cir.ptr<!ty_22T22> -> !cir.ptr<!s32i>
// CHECK-NEXT: [[B_STORAGE0:%.*]] = cir.get_member [[FI_EL]][1] {name = "b"} : !cir.ptr<!ty_22T22> -> !cir.ptr<!s64i>
// CHECK-NEXT: [[X_VAL:%.*]] = cir.load [[X_ALLOCA]] : cir.ptr <!s32i>, !s32i
// CHECK-NEXT: [[X_CASTED:%.*]] = cir.cast(integral, [[X_VAL]] : !s32i), !s64i
// CHECK-NEXT: cir.store [[X_CASTED]], [[B_STORAGE0]] : !s64i, cir.ptr <!s64i>
// CHECK-NEXT: [[ONE:%.*]] = cir.const(#cir.int<1> : !s64i) : !s64i
// CHECK-NEXT: [[SE_EL:%.*]] = cir.ptr_stride([[FI_EL]] : !cir.ptr<!ty_22T22>, [[ONE]] : !s64i), !cir.ptr<!ty_22T22>
// CHECK-NEXT: [[A_STORAGE1:%.*]] = cir.get_member [[SE_EL]][0] {name = "a"} : !cir.ptr<!ty_22T22> -> !cir.ptr<!s32i>
// CHECK-NEXT: [[B_STORAGE1:%.*]] = cir.get_member [[SE_EL]][1] {name = "b"} : !cir.ptr<!ty_22T22> -> !cir.ptr<!s64i>
// CHECK-NEXT: cir.return

void foo() {
double bar[] = {9,8,7};
}
Expand Down

0 comments on commit 436d728

Please sign in to comment.