Skip to content

[CIR][CodeGen] supports struct copy from function call result #369

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {

enum ExprValueKind { EVK_RValue, EVK_NonRValue };

/// Perform the final copy to DestPtr, if desired.
void buildFinalDestCopy(QualType type, RValue src);

/// Perform the final copy to DestPtr, if desired. SrcIsRValue is true if
/// source comes from an RValue.
void buildFinalDestCopy(QualType type, const LValue &src,
Expand Down Expand Up @@ -331,6 +334,13 @@ void AggExprEmitter::buildAggLoadOfLValue(const Expr *E) {
buildFinalDestCopy(E->getType(), LV);
}

/// Perform the final copy to DestPtr, if desired.
void AggExprEmitter::buildFinalDestCopy(QualType type, RValue src) {
assert(src.isAggregate() && "value must be aggregate value!");
LValue srcLV = CGF.makeAddrLValue(src.getAggregateAddress(), type);
buildFinalDestCopy(type, srcLV, EVK_RValue);
}

/// Perform the final copy to DestPtr, if desired.
void AggExprEmitter::buildFinalDestCopy(QualType type, const LValue &src,
ExprValueKind SrcValueKind) {
Expand All @@ -342,11 +352,13 @@ void AggExprEmitter::buildFinalDestCopy(QualType type, const LValue &src,
return;

// Copy non-trivial C structs here.
if (Dest.isVolatile() || UnimplementedFeature::volatileTypes())
llvm_unreachable("volatile is NYI");
if (Dest.isVolatile())
assert(!UnimplementedFeature::volatileTypes());

if (SrcValueKind == EVK_RValue) {
llvm_unreachable("rvalue is NYI");
if (type.isNonTrivialToPrimitiveDestructiveMove() == QualType::PCK_Struct) {
llvm_unreachable("move assignment/move ctor for rvalue is NYI");
}
} else {
if (type.isNonTrivialToPrimitiveCopy() == QualType::PCK_Struct)
llvm_unreachable("non-trivial primitive copy is NYI");
Expand Down Expand Up @@ -808,7 +820,9 @@ void AggExprEmitter::withReturnValueSlot(
if (!UseTemp) {
RetAddr = Dest.getAddress();
} else {
llvm_unreachable("NYI");
RetAddr = CGF.CreateMemTemp(RetTy, CGF.getLoc(E->getSourceRange()),
"tmp", &RetAddr);
assert(!UnimplementedFeature::shouldEmitLifetimeMarkers() && "NYI");
}

RValue Src =
Expand All @@ -819,14 +833,13 @@ void AggExprEmitter::withReturnValueSlot(
return;

assert(Dest.isIgnored() || Dest.getPointer() != Src.getAggregatePointer());
llvm_unreachable("NYI");
// TODO(cir): EmitFinalDestCopy(E->getType(), Src);
buildFinalDestCopy(E->getType(), Src);

if (!RequiresDestruction) {
// If there's no dtor to run, the copy was the last use of our temporary.
// Since we're not guaranteed to be in an ExprWithCleanups, clean up
// eagerly.
llvm_unreachable("NYI");
assert(!UnimplementedFeature::shouldEmitLifetimeMarkers() && "NYI");
}
}

Expand Down
13 changes: 13 additions & 0 deletions clang/test/CIR/CodeGen/agg-copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,17 @@ A foo3(void) {
// CHECK: cir.copy [[TMP2]] to [[TMP1]] : !cir.ptr<!ty_22A22>
void foo4(A* a1) {
A a2 = *a1;
}

A create() { A a; return a; }

// CHECK: cir.func {{.*@foo5}}
// CHECK: [[TMP0]] = cir.alloca !ty_22A22, cir.ptr <!ty_22A22>,
// CHECK: [[TMP1]] = cir.alloca !ty_22A22, cir.ptr <!ty_22A22>, ["tmp"] {alignment = 4 : i64}
// CHECK: [[TMP2]] = cir.call @create() : () -> !ty_22A22
// CHECK: cir.store [[TMP2]], [[TMP1]] : !ty_22A22, cir.ptr <!ty_22A22>
// CHECK: cir.copy [[TMP1]] to [[TMP0]] : !cir.ptr<!ty_22A22>
void foo5() {
A a;
a = create();
}