Skip to content

Commit e9fc768

Browse files
authored
[CIR] Upstream basic support for sizeof and alignof (llvm#130847)
This change adds the essential support for sizeof and alignof operators - Support for VariableArrayType can be added after closing llvm#130197
1 parent 3ec693d commit e9fc768

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

+40
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
9292

9393
mlir::Value VisitCastExpr(CastExpr *E);
9494

95+
mlir::Value VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *e);
96+
9597
/// Emit a conversion from the specified type to the specified destination
9698
/// type, both of which are CIR scalar types.
9799
/// TODO: do we need ScalarConversionOpts here? Should be done in another
@@ -148,3 +150,41 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
148150
}
149151
return {};
150152
}
153+
154+
/// Return the size or alignment of the type of argument of the sizeof
155+
/// expression as an integer.
156+
mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
157+
const UnaryExprOrTypeTraitExpr *e) {
158+
const QualType typeToSize = e->getTypeOfArgument();
159+
const mlir::Location loc = cgf.getLoc(e->getSourceRange());
160+
if (auto kind = e->getKind();
161+
kind == UETT_SizeOf || kind == UETT_DataSizeOf) {
162+
if (const VariableArrayType *variableArrTy =
163+
cgf.getContext().getAsVariableArrayType(typeToSize)) {
164+
cgf.getCIRGenModule().errorNYI(e->getSourceRange(),
165+
"sizeof operator for VariableArrayType",
166+
e->getStmtClassName());
167+
return builder.getConstant(
168+
loc, builder.getAttr<cir::IntAttr>(
169+
cgf.cgm.UInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true)));
170+
}
171+
} else if (e->getKind() == UETT_OpenMPRequiredSimdAlign) {
172+
cgf.getCIRGenModule().errorNYI(
173+
e->getSourceRange(), "sizeof operator for OpenMpRequiredSimdAlign",
174+
e->getStmtClassName());
175+
return builder.getConstant(
176+
loc, builder.getAttr<cir::IntAttr>(
177+
cgf.cgm.UInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true)));
178+
} else if (e->getKind() == UETT_VectorElements) {
179+
cgf.getCIRGenModule().errorNYI(e->getSourceRange(),
180+
"sizeof operator for VectorElements",
181+
e->getStmtClassName());
182+
return builder.getConstant(
183+
loc, builder.getAttr<cir::IntAttr>(
184+
cgf.cgm.UInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true)));
185+
}
186+
187+
return builder.getConstant(
188+
loc, builder.getAttr<cir::IntAttr>(
189+
cgf.cgm.UInt64Ty, e->EvaluateKnownConstInt(cgf.getContext())));
190+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - 2>&1 | filecheck %s
2+
3+
void foo() {
4+
unsigned long b = sizeof(bool);
5+
// CHECK: cir.const #cir.int<1> : !cir.int<u, 64>
6+
7+
unsigned long i = sizeof(int);
8+
// CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
9+
10+
unsigned long l = sizeof(long);
11+
// CHECK: cir.const #cir.int<8> : !cir.int<u, 64>
12+
13+
unsigned long f = sizeof(float);
14+
// CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
15+
16+
unsigned long d = sizeof(double);
17+
// CHECK: cir.const #cir.int<8> : !cir.int<u, 64>
18+
19+
unsigned long iArr = sizeof(int[5]);
20+
// CHECK: cir.const #cir.int<20> : !cir.int<u, 64>
21+
22+
unsigned long dArr = sizeof(double[5]);
23+
// CHECK: cir.const #cir.int<40> : !cir.int<u, 64>
24+
}
25+
26+
void foo2() {
27+
unsigned long b = alignof(bool);
28+
// CHECK: cir.const #cir.int<1> : !cir.int<u, 64>
29+
30+
unsigned long i = alignof(int);
31+
// CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
32+
33+
unsigned long l = alignof(long);
34+
// CHECK: cir.const #cir.int<8> : !cir.int<u, 64>
35+
36+
unsigned long f = alignof(float);
37+
// CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
38+
39+
unsigned long d = alignof(double);
40+
// CHECK: cir.const #cir.int<8> : !cir.int<u, 64>
41+
42+
unsigned long iArr = alignof(int[5]);
43+
// CHECK: cir.const #cir.int<4> : !cir.int<u, 64>
44+
45+
unsigned long dArr = alignof(double[5]);
46+
// CHECK: cir.const #cir.int<8> : !cir.int<u, 64>
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - 2>&1 | FileCheck %s
2+
3+
void foo() {
4+
unsigned long b = sizeof(bool);
5+
// CHECK: store i64 1, ptr {{%.*}}, align 4
6+
7+
unsigned long i = sizeof(int);
8+
// CHECK: store i64 4, ptr {{%.*}}, align 4
9+
10+
unsigned long l = sizeof(long);
11+
// CHECK: store i64 8, ptr {{%.*}}, align 4
12+
13+
unsigned long f = sizeof(float);
14+
// CHECK: store i64 4, ptr {{%.*}}, align 4
15+
16+
unsigned long d = sizeof(double);
17+
// CHECK: store i64 8, ptr {{%.*}}, align 4
18+
19+
unsigned long iArr = sizeof(float[5]);
20+
// CHECK: store i64 20, ptr {{%.*}}, align 4
21+
22+
unsigned long dArr = sizeof(double[5]);
23+
// CHECK: store i64 40, ptr {{%.*}}, align 4
24+
}
25+
26+
void foo2() {
27+
unsigned long b = alignof(bool);
28+
// CHECK: store i64 1, ptr {{%.*}}, align 4
29+
30+
unsigned long i = alignof(int);
31+
// CHECK: store i64 4, ptr {{%.*}}, align 4
32+
33+
unsigned long l = alignof(long);
34+
// CHECK: store i64 8, ptr {{%.*}}, align 4
35+
36+
unsigned long f = alignof(float);
37+
// CHECK: store i64 4, ptr {{%.*}}, align 4
38+
39+
unsigned long d = alignof(double);
40+
// CHECK: store i64 8, ptr {{%.*}}, align 4
41+
42+
unsigned long iArr = alignof(int[5]);
43+
// CHECK: store i64 4, ptr {{%.*}}, align 4
44+
45+
unsigned long dArr = alignof(double[5]);
46+
// CHECK: store i64 8, ptr {{%.*}}, align 4
47+
}

0 commit comments

Comments
 (0)