Skip to content

Commit a83dcd3

Browse files
committed
[CIR] Upstream CompoundLiteralExpr for Scalar
1 parent b84f72a commit a83dcd3

File tree

5 files changed

+116
-0
lines changed

5 files changed

+116
-0
lines changed

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,68 @@ LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {
10531053
llvm_unreachable("Unhandled member declaration!");
10541054
}
10551055

1056+
/// Evaluate an expression into a given memory location.
1057+
void CIRGenFunction::emitAnyExprToMem(const Expr *e, Address location,
1058+
Qualifiers quals, bool isInit) {
1059+
// FIXME: This function should take an LValue as an argument.
1060+
switch (getEvaluationKind(e->getType())) {
1061+
case cir::TEK_Complex: {
1062+
RValue rv = RValue::get(emitComplexExpr(e));
1063+
LValue lv = makeAddrLValue(location, e->getType());
1064+
emitStoreThroughLValue(rv, lv);
1065+
return;
1066+
}
1067+
1068+
case cir::TEK_Aggregate: {
1069+
emitAggExpr(e, AggValueSlot::forAddr(location, quals,
1070+
AggValueSlot::IsDestructed_t(isInit),
1071+
AggValueSlot::IsAliased_t(!isInit),
1072+
AggValueSlot::MayOverlap));
1073+
return;
1074+
}
1075+
1076+
case cir::TEK_Scalar: {
1077+
RValue rv = RValue::get(emitScalarExpr(e));
1078+
LValue lv = makeAddrLValue(location, e->getType());
1079+
emitStoreThroughLValue(rv, lv);
1080+
return;
1081+
}
1082+
}
1083+
1084+
llvm_unreachable("bad evaluation kind");
1085+
}
1086+
1087+
LValue CIRGenFunction::emitCompoundLiteralLValue(const CompoundLiteralExpr *e) {
1088+
if (e->isFileScope()) {
1089+
cgm.errorNYI(e->getSourceRange(), "emitCompoundLiteralLValue: FileScope");
1090+
return {};
1091+
}
1092+
1093+
if (e->getType()->isVariablyModifiedType()) {
1094+
cgm.errorNYI(e->getSourceRange(),
1095+
"emitCompoundLiteralLValue: VariablyModifiedType");
1096+
return {};
1097+
}
1098+
1099+
Address declPtr = createMemTemp(e->getType(), getLoc(e->getSourceRange()),
1100+
".compoundliteral");
1101+
const Expr *initExpr = e->getInitializer();
1102+
LValue result = makeAddrLValue(declPtr, e->getType(), AlignmentSource::Decl);
1103+
1104+
emitAnyExprToMem(initExpr, declPtr, e->getType().getQualifiers(),
1105+
/*Init*/ true);
1106+
1107+
// Block-scope compound literals are destroyed at the end of the enclosing
1108+
// scope in C.
1109+
if (!getLangOpts().CPlusPlus && e->getType().isDestructedType()) {
1110+
cgm.errorNYI(e->getSourceRange(),
1111+
"emitCompoundLiteralLValue: non C++ DestructedType");
1112+
return {};
1113+
}
1114+
1115+
return result;
1116+
}
1117+
10561118
LValue CIRGenFunction::emitCallExprLValue(const CallExpr *e) {
10571119
RValue rv = emitCallExpr(e);
10581120

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
233233

234234
mlir::Value VisitMemberExpr(MemberExpr *e);
235235

236+
mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
237+
return emitLoadOfLValue(e);
238+
}
239+
236240
mlir::Value VisitInitListExpr(InitListExpr *e);
237241

238242
mlir::Value VisitExplicitCastExpr(ExplicitCastExpr *e) {

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,8 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
698698
return emitStringLiteralLValue(cast<StringLiteral>(e));
699699
case Expr::MemberExprClass:
700700
return emitMemberExpr(cast<MemberExpr>(e));
701+
case Expr::CompoundLiteralExprClass:
702+
return emitCompoundLiteralLValue(cast<CompoundLiteralExpr>(e));
701703
case Expr::BinaryOperatorClass:
702704
return emitBinaryOperatorLValue(cast<BinaryOperator>(e));
703705
case Expr::CompoundAssignOperatorClass: {

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,11 @@ class CIRGenFunction : public CIRGenTypeCache {
757757
RValue emitAnyExpr(const clang::Expr *e,
758758
AggValueSlot aggSlot = AggValueSlot::ignored());
759759

760+
/// Emits the code necessary to evaluate an arbitrary expression into the
761+
/// given memory location.
762+
void emitAnyExprToMem(const Expr *e, Address location, Qualifiers quals,
763+
bool isInitializer);
764+
760765
/// Similarly to emitAnyExpr(), however, the result will always be accessible
761766
/// even if no aggregate location is provided.
762767
RValue emitAnyExprToTemp(const clang::Expr *e);
@@ -828,6 +833,7 @@ class CIRGenFunction : public CIRGenTypeCache {
828833
mlir::Value emitCheckedArgForAssume(const Expr *e);
829834

830835
LValue emitCompoundAssignmentLValue(const clang::CompoundAssignOperator *e);
836+
LValue emitCompoundLiteralLValue(const CompoundLiteralExpr *e);
831837

832838
void emitConstructorBody(FunctionArgList &args);
833839
void emitDestructorBody(FunctionArgList &args);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
7+
8+
int foo() {
9+
int e = (int){1};
10+
return e;
11+
}
12+
13+
// CIR: %[[RET:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
14+
// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init]
15+
// CIR: %[[COMPOUND:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, [".compoundliteral", init]
16+
// CIR: %[[VALUE:.*]] = cir.const #cir.int<1> : !s32i
17+
// CIR: cir.store{{.*}} %[[VALUE]], %[[COMPOUND]] : !s32i, !cir.ptr<!s32i>
18+
// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[COMPOUND]] : !cir.ptr<!s32i>, !s32i
19+
// CIR: cir.store{{.*}} %[[TMP]], %[[INIT]] : !s32i, !cir.ptr<!s32i>
20+
// CIR: %[[TMP_2:.*]] = cir.load{{.*}} %[[INIT]] : !cir.ptr<!s32i>, !s32i
21+
// CIR: cir.store %[[TMP_2]], %[[RET]] : !s32i, !cir.ptr<!s32i>
22+
// CIR: %[[TMP_3:.*]] = cir.load %[[RET]] : !cir.ptr<!s32i>, !s32i
23+
// CIR: cir.return %[[TMP_3]] : !s32i
24+
25+
// LLVM: %[[RET:.*]] = alloca i32, i64 1, align 4
26+
// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4
27+
// LLVM: %[[COMPOUND:.*]] = alloca i32, i64 1, align 4
28+
// LLVM: store i32 1, ptr %[[COMPOUND]], align 4
29+
// LLVM: %[[TMP:.*]] = load i32, ptr %[[COMPOUND]], align 4
30+
// LLVM: store i32 %[[TMP]], ptr %[[INIT]], align 4
31+
// LLVM: %[[TMP_2:.*]] = load i32, ptr %[[INIT]], align 4
32+
// LLVM: store i32 %[[TMP_2]], ptr %[[RET]], align 4
33+
// LLVM: %[[TMP_3:.*]] = load i32, ptr %[[RET]], align 4
34+
// LLVM: ret i32 %[[TMP_3]]
35+
36+
// OGCG: %[[INIT:.*]] = alloca i32, align 4
37+
// OGCG: %[[COMPOUND:.*]] = alloca i32, align 4
38+
// OGCG: store i32 1, ptr %[[COMPOUND]], align 4
39+
// OGCG: %[[TMP:.*]] = load i32, ptr %[[COMPOUND]], align 4
40+
// OGCG: store i32 %[[TMP]], ptr %[[INIT]], align 4
41+
// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[INIT]], align 4
42+
// OGCG: ret i32 %[[TMP_2]]

0 commit comments

Comments
 (0)