Author: Amr Hesham
Date: 2025-03-14T19:12:27+01:00
New Revision: e9fc7683a54d9e5233cff5d016d6f2cdcaf2b2c3

URL: 
https://github.com/llvm/llvm-project/commit/e9fc7683a54d9e5233cff5d016d6f2cdcaf2b2c3
DIFF: 
https://github.com/llvm/llvm-project/commit/e9fc7683a54d9e5233cff5d016d6f2cdcaf2b2c3.diff

LOG: [CIR] Upstream basic support for sizeof and alignof (#130847)

This change adds the essential support for sizeof and alignof operators

- Support for VariableArrayType can be added after closing #130197

Added: 
    clang/test/CIR/CodeGen/unary-expr-or-type-trait.cpp
    clang/test/CIR/Lowering/unary-expr-or-type-trait.cpp

Modified: 
    clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index b9e56dc4123d6..9bd6855b17c3c 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,41 @@ 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();
+  const mlir::Location loc = cgf.getLoc(e->getSourceRange());
+  if (auto kind = e->getKind();
+      kind == UETT_SizeOf || kind == UETT_DataSizeOf) {
+    if (const VariableArrayType *variableArrTy =
+            cgf.getContext().getAsVariableArrayType(typeToSize)) {
+      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.getConstant(
+      loc, 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..fe4344c34f3e5
--- /dev/null
+++ b/clang/test/CIR/CodeGen/unary-expr-or-type-trait.cpp
@@ -0,0 +1,47 @@
+// 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>
+
+  unsigned long iArr = sizeof(int[5]);
+  // CHECK: cir.const #cir.int<20> : !cir.int<u, 64>
+
+  unsigned long dArr =  sizeof(double[5]);
+  // CHECK: cir.const #cir.int<40> : !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>
+
+  unsigned long iArr = alignof(int[5]);
+  // CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
+
+  unsigned long dArr =  alignof(double[5]);
+  // 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..edf6ed7f58757
--- /dev/null
+++ b/clang/test/CIR/Lowering/unary-expr-or-type-trait.cpp
@@ -0,0 +1,47 @@
+// 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
+
+  unsigned long iArr =  sizeof(float[5]);
+  // CHECK: store i64 20, ptr {{%.*}}, align 4
+
+  unsigned long dArr =  sizeof(double[5]);
+  // CHECK: store i64 40, 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
+
+  unsigned long iArr =  alignof(int[5]);
+  // CHECK: store i64 4, ptr {{%.*}}, align 4
+
+  unsigned long dArr =  alignof(double[5]);
+  // CHECK: store i64 8, ptr {{%.*}}, align 4
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to