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