[clang] [CIR] Upstream basic support for sizeof and alignof (PR #130847)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 12 14:15:57 PDT 2025
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/130847
>From 337b23e5ddb8ad9ef470e9c62d6fc136ccb070ee Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Tue, 11 Mar 2025 22:42:28 +0100
Subject: [PATCH 1/3] [CIR] Upstream basic support for sizeof and alignof
---
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 26 ++++++++++++++
.../CIR/CodeGen/unary-expr-or-type-trait.cpp | 35 +++++++++++++++++++
.../CIR/Lowering/unary-expr-or-type-trait.cpp | 35 +++++++++++++++++++
3 files changed, 96 insertions(+)
create mode 100644 clang/test/CIR/CodeGen/unary-expr-or-type-trait.cpp
create mode 100644 clang/test/CIR/Lowering/unary-expr-or-type-trait.cpp
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index b9e56dc4123d6..19d57ed9cf6fa 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -92,6 +92,8 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
mlir::Value VisitCastExpr(CastExpr *E);
+ mlir::Value VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *e);
+
/// Emit a conversion from the specified type to the specified destination
/// type, both of which are CIR scalar types.
/// TODO: do we need ScalarConversionOpts here? Should be done in another
@@ -148,3 +150,27 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
}
return {};
}
+
+/// Return the size or alignment of the type of argument of the sizeof
+/// expression as an integer.
+mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
+ const UnaryExprOrTypeTraitExpr *e) {
+ const QualType typeToSize = e->getTypeOfArgument();
+ if (e->getKind() == UETT_SizeOf) {
+ if (const VariableArrayType *variableArrTy =
+ cgf.getContext().getAsVariableArrayType(typeToSize)) {
+ cgf.getCIRGenModule().errorNYI(e->getSourceRange(),
+ "sizeof operator for VariableArrayType",
+ e->getStmtClassName());
+ }
+ } else if (e->getKind() == UETT_OpenMPRequiredSimdAlign) {
+ cgf.getCIRGenModule().errorNYI(
+ e->getSourceRange(),
+ "sizeof operator for Not yet implemented: ", e->getStmtClassName());
+ }
+
+ return builder.create<cir::ConstantOp>(
+ cgf.getLoc(e->getSourceRange()), cgf.cgm.UInt64Ty,
+ builder.getAttr<cir::IntAttr>(
+ cgf.cgm.UInt64Ty, e->EvaluateKnownConstInt(cgf.getContext())));
+}
diff --git a/clang/test/CIR/CodeGen/unary-expr-or-type-trait.cpp b/clang/test/CIR/CodeGen/unary-expr-or-type-trait.cpp
new file mode 100644
index 0000000000000..e1868d99c42b6
--- /dev/null
+++ b/clang/test/CIR/CodeGen/unary-expr-or-type-trait.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - 2>&1 | filecheck %s
+
+void foo() {
+ unsigned long b = sizeof(bool);
+ // CHECK: cir.const #cir.int<1> : !cir.int<u, 64>
+
+ unsigned long i = sizeof(int);
+ // CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
+
+ unsigned long l = sizeof(long);
+ // CHECK: cir.const #cir.int<8> : !cir.int<u, 64>
+
+ unsigned long f = sizeof(float);
+ // CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
+
+ unsigned long d = sizeof(double);
+ // CHECK: cir.const #cir.int<8> : !cir.int<u, 64>
+}
+
+void foo2() {
+ unsigned long b = alignof(bool);
+ // CHECK: cir.const #cir.int<1> : !cir.int<u, 64>
+
+ unsigned long i = alignof(int);
+ // CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
+
+ unsigned long l = alignof(long);
+ // CHECK: cir.const #cir.int<8> : !cir.int<u, 64>
+
+ unsigned long f = alignof(float);
+ // CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
+
+ unsigned long d = alignof(double);
+ // CHECK: cir.const #cir.int<8> : !cir.int<u, 64>
+}
diff --git a/clang/test/CIR/Lowering/unary-expr-or-type-trait.cpp b/clang/test/CIR/Lowering/unary-expr-or-type-trait.cpp
new file mode 100644
index 0000000000000..551a1c254216b
--- /dev/null
+++ b/clang/test/CIR/Lowering/unary-expr-or-type-trait.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - 2>&1 | FileCheck %s
+
+void foo() {
+ unsigned long b = sizeof(bool);
+ // CHECK: store i64 1, ptr {{%.*}}, align 4
+
+ unsigned long i = sizeof(int);
+ // CHECK: store i64 4, ptr {{%.*}}, align 4
+
+ unsigned long l = sizeof(long);
+ // CHECK: store i64 8, ptr {{%.*}}, align 4
+
+ unsigned long f = sizeof(float);
+ // CHECK: store i64 4, ptr {{%.*}}, align 4
+
+ unsigned long d = sizeof(double);
+ // CHECK: store i64 8, ptr {{%.*}}, align 4
+}
+
+void foo2() {
+ unsigned long b = alignof(bool);
+ // CHECK: store i64 1, ptr {{%.*}}, align 4
+
+ unsigned long i = alignof(int);
+ // CHECK: store i64 4, ptr {{%.*}}, align 4
+
+ unsigned long l = alignof(long);
+ // CHECK: store i64 8, ptr {{%.*}}, align 4
+
+ unsigned long f = alignof(float);
+ // CHECK: store i64 4, ptr {{%.*}}, align 4
+
+ unsigned long d = alignof(double);
+ // CHECK: store i64 8, ptr {{%.*}}, align 4
+}
>From 858383e0a56eb8d89476541733503dcbe5a1fcc9 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Tue, 11 Mar 2025 23:22:26 +0100
Subject: [PATCH 2/3] Update VisitUnaryExprOrTypeTraitExpr
---
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 19d57ed9cf6fa..71cbcbe04a4a2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -156,7 +156,8 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *e) {
const QualType typeToSize = e->getTypeOfArgument();
- if (e->getKind() == UETT_SizeOf) {
+ if (auto kind = e->getKind();
+ kind == UETT_SizeOf || kind == UETT_DataSizeOf) {
if (const VariableArrayType *variableArrTy =
cgf.getContext().getAsVariableArrayType(typeToSize)) {
cgf.getCIRGenModule().errorNYI(e->getSourceRange(),
@@ -165,8 +166,12 @@ mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
}
} else if (e->getKind() == UETT_OpenMPRequiredSimdAlign) {
cgf.getCIRGenModule().errorNYI(
- e->getSourceRange(),
- "sizeof operator for Not yet implemented: ", e->getStmtClassName());
+ e->getSourceRange(), "sizeof operator for OpenMpRequiredSimdAlign",
+ e->getStmtClassName());
+ } else if (e->getKind() == UETT_VectorElements) {
+ cgf.getCIRGenModule().errorNYI(e->getSourceRange(),
+ "sizeof operator for VectorElements",
+ e->getStmtClassName());
}
return builder.create<cir::ConstantOp>(
>From ec780a786442b4cf456feecbda2edadcc196b533 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Wed, 12 Mar 2025 22:15:34 +0100
Subject: [PATCH 3/3] Add recovering value for NYI cases
---
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 71cbcbe04a4a2..9bd6855b17c3c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -156,6 +156,7 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *e) {
const QualType typeToSize = e->getTypeOfArgument();
+ const mlir::Location loc = cgf.getLoc(e->getSourceRange());
if (auto kind = e->getKind();
kind == UETT_SizeOf || kind == UETT_DataSizeOf) {
if (const VariableArrayType *variableArrTy =
@@ -163,19 +164,27 @@ mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
cgf.getCIRGenModule().errorNYI(e->getSourceRange(),
"sizeof operator for VariableArrayType",
e->getStmtClassName());
+ return builder.getConstant(
+ loc, builder.getAttr<cir::IntAttr>(
+ cgf.cgm.UInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true)));
}
} else if (e->getKind() == UETT_OpenMPRequiredSimdAlign) {
cgf.getCIRGenModule().errorNYI(
e->getSourceRange(), "sizeof operator for OpenMpRequiredSimdAlign",
e->getStmtClassName());
+ return builder.getConstant(
+ loc, builder.getAttr<cir::IntAttr>(
+ cgf.cgm.UInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true)));
} else if (e->getKind() == UETT_VectorElements) {
cgf.getCIRGenModule().errorNYI(e->getSourceRange(),
"sizeof operator for VectorElements",
e->getStmtClassName());
+ return builder.getConstant(
+ loc, builder.getAttr<cir::IntAttr>(
+ cgf.cgm.UInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true)));
}
- return builder.create<cir::ConstantOp>(
- cgf.getLoc(e->getSourceRange()), cgf.cgm.UInt64Ty,
- builder.getAttr<cir::IntAttr>(
- cgf.cgm.UInt64Ty, e->EvaluateKnownConstInt(cgf.getContext())));
+ return builder.getConstant(
+ loc, builder.getAttr<cir::IntAttr>(
+ cgf.cgm.UInt64Ty, e->EvaluateKnownConstInt(cgf.getContext())));
}
More information about the cfe-commits
mailing list