[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