[clang] [CIR] Upstream basic support for sizeof and alignof (PR #130847)

Amr Hesham via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 11 14:47:13 PDT 2025


https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/130847

This change adds the essential support for sizeof and alignof operators

- Support for VariableArrayType can be added after closing #130197


>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] [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
+}



More information about the cfe-commits mailing list