From 6bf3852320a2ea0d83e3f6237e2e1ba97bbf2121 Mon Sep 17 00:00:00 2001 From: gitoleg Date: Fri, 6 Dec 2024 14:51:49 +0300 Subject: [PATCH 1/6] [CIR][CIRGen] fixes functions calls with ret values and cleanup stage --- clang/lib/CIR/CodeGen/CIRGenCall.cpp | 16 +++++++++++ clang/test/CIR/CodeGen/try-catch-dtors.cpp | 31 ++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index 29db13706437..def1061ae45e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -889,6 +889,22 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo, auto Results = theCall->getOpResults(); assert(Results.size() <= 1 && "multiple returns NYI"); assert(Results[0].getType() == RetCIRTy && "Bitcast support NYI"); + + auto reg = builder.getBlock()->getParent(); + if (reg != theCall->getParentRegion()) { + Address DestPtr = ReturnValue.getValue(); + + if (!DestPtr.isValid()) + DestPtr = CreateMemTemp(RetTy, callLoc, "tmp"); + + auto ip = builder.saveInsertionPoint(); + builder.setInsertionPointAfter(theCall); + builder.createStore(callLoc, Results[0], DestPtr); + builder.restoreInsertionPoint(ip); + auto load = builder.createLoad(callLoc, DestPtr); + return RValue::get(load); + } + return RValue::get(Results[0]); } default: diff --git a/clang/test/CIR/CodeGen/try-catch-dtors.cpp b/clang/test/CIR/CodeGen/try-catch-dtors.cpp index 40c35434e17c..849fbcde4e76 100644 --- a/clang/test/CIR/CodeGen/try-catch-dtors.cpp +++ b/clang/test/CIR/CodeGen/try-catch-dtors.cpp @@ -308,3 +308,34 @@ void yo2(bool x) { // CIR: } catch [type #cir.all { // CIR: cir.catch_param -> !cir.ptr // CIR: }] + + +int foo() { return 42; } + +struct A { + ~A() {} +}; + +void bar() { + A a; + int b = foo(); +} + +// CIR-LABEL: @_Z3barv +// CIR: %[[V0:.*]] = cir.alloca !ty_A, !cir.ptr, ["a"] {alignment = 1 : i64} +// CIR: %[[V1:.*]] = cir.alloca !s32i, !cir.ptr, ["b", init] {alignment = 4 : i64} +// CIR: %[[V2:.*]] = cir.alloca !s32i, !cir.ptr, ["tmp"] {alignment = 4 : i64} +// CIR: cir.try synthetic cleanup { +// CIR: %[[V4:.*]] = cir.call exception @_Z3foov() : () -> !s32i cleanup { +// CIR: cir.call @_ZN1AD2Ev(%[[V0]]) : (!cir.ptr) -> () extra(#fn_attr) +// CIR: cir.yield +// CIR: } +// CIR: cir.store %[[V4]], %[[V2]] : !s32i, !cir.ptr +// CIR: cir.yield +// CIR: } catch [#cir.unwind { +// CIR: cir.resume +// CIR: }] +// CIR: %[[V3:.*]] = cir.load %[[V2]] : !cir.ptr, !s32i +// CIR: cir.store %[[V3]], %[[V1]] : !s32i, !cir.ptr +// CIR: cir.call @_ZN1AD2Ev(%[[V0]]) : (!cir.ptr) -> () extra(#fn_attr) +// CIR: cir.return From c78799e9cfb230e9d489f339d433d8f1363480df Mon Sep 17 00:00:00 2001 From: gitoleg Date: Tue, 10 Dec 2024 16:53:26 +0300 Subject: [PATCH 2/6] adds helper function --- clang/lib/CIR/CodeGen/CIRGenCall.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index def1061ae45e..2851d634f4b0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -551,6 +551,18 @@ static cir::CIRCallOpInterface emitCallLikeOp( extraFnAttrs); } +static RValue getRValueThroughMemory(mlir::Location loc, + CIRGenBuilderTy &builder, + mlir::Value val, + Address addr) { + auto ip = builder.saveInsertionPoint(); + builder.setInsertionPointAfterValue(val); + builder.createStore(loc, val, addr); + builder.restoreInsertionPoint(ip); + auto load = builder.createLoad(loc, addr); + return RValue::get(load); +} + RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo, const CIRGenCallee &Callee, ReturnValueSlot ReturnValue, @@ -890,19 +902,15 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo, assert(Results.size() <= 1 && "multiple returns NYI"); assert(Results[0].getType() == RetCIRTy && "Bitcast support NYI"); - auto reg = builder.getBlock()->getParent(); - if (reg != theCall->getParentRegion()) { + auto region = builder.getBlock()->getParent(); + if (region != theCall->getParentRegion()) { Address DestPtr = ReturnValue.getValue(); if (!DestPtr.isValid()) DestPtr = CreateMemTemp(RetTy, callLoc, "tmp"); - auto ip = builder.saveInsertionPoint(); - builder.setInsertionPointAfter(theCall); - builder.createStore(callLoc, Results[0], DestPtr); - builder.restoreInsertionPoint(ip); - auto load = builder.createLoad(callLoc, DestPtr); - return RValue::get(load); + return getRValueThroughMemory(callLoc, builder, Results[0], + DestPtr); } return RValue::get(Results[0]); From 24b91c68ebdd1506018095d4c226e4091088a5fe Mon Sep 17 00:00:00 2001 From: gitoleg Date: Tue, 10 Dec 2024 16:58:32 +0300 Subject: [PATCH 3/6] clang-format ... --- clang/lib/CIR/CodeGen/CIRGenCall.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index 2851d634f4b0..ac8736ebabbd 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -552,8 +552,7 @@ static cir::CIRCallOpInterface emitCallLikeOp( } static RValue getRValueThroughMemory(mlir::Location loc, - CIRGenBuilderTy &builder, - mlir::Value val, + CIRGenBuilderTy &builder, mlir::Value val, Address addr) { auto ip = builder.saveInsertionPoint(); builder.setInsertionPointAfterValue(val); From 6846da47eacc7be55e2b512678affd218c0769e6 Mon Sep 17 00:00:00 2001 From: gitoleg Date: Fri, 13 Dec 2024 16:36:48 +0300 Subject: [PATCH 4/6] minor --- clang/lib/CIR/CodeGen/CIRGenCall.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index ac8736ebabbd..ebf30c7d9fe6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -901,12 +901,12 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo, assert(Results.size() <= 1 && "multiple returns NYI"); assert(Results[0].getType() == RetCIRTy && "Bitcast support NYI"); - auto region = builder.getBlock()->getParent(); + mlir::Region *region region = builder.getBlock()->getParent(); if (region != theCall->getParentRegion()) { Address DestPtr = ReturnValue.getValue(); if (!DestPtr.isValid()) - DestPtr = CreateMemTemp(RetTy, callLoc, "tmp"); + DestPtr = CreateMemTemp(RetTy, callLoc, "tmp.try.call.res"); return getRValueThroughMemory(callLoc, builder, Results[0], DestPtr); From 526fc86076a5bc6a838f5b92bd75a06526b7c3ad Mon Sep 17 00:00:00 2001 From: gitoleg Date: Fri, 13 Dec 2024 16:57:18 +0300 Subject: [PATCH 5/6] fixed tests --- clang/test/CIR/CodeGen/try-catch-dtors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CIR/CodeGen/try-catch-dtors.cpp b/clang/test/CIR/CodeGen/try-catch-dtors.cpp index 849fbcde4e76..5cf0bf0a1a0b 100644 --- a/clang/test/CIR/CodeGen/try-catch-dtors.cpp +++ b/clang/test/CIR/CodeGen/try-catch-dtors.cpp @@ -324,7 +324,7 @@ void bar() { // CIR-LABEL: @_Z3barv // CIR: %[[V0:.*]] = cir.alloca !ty_A, !cir.ptr, ["a"] {alignment = 1 : i64} // CIR: %[[V1:.*]] = cir.alloca !s32i, !cir.ptr, ["b", init] {alignment = 4 : i64} -// CIR: %[[V2:.*]] = cir.alloca !s32i, !cir.ptr, ["tmp"] {alignment = 4 : i64} +// CIR: %[[V2:.*]] = cir.alloca !s32i, !cir.ptr, ["tmp.try.call.res"] {alignment = 4 : i64} // CIR: cir.try synthetic cleanup { // CIR: %[[V4:.*]] = cir.call exception @_Z3foov() : () -> !s32i cleanup { // CIR: cir.call @_ZN1AD2Ev(%[[V0]]) : (!cir.ptr) -> () extra(#fn_attr) From 21369d88a1bae85be35b81159649c891cd861822 Mon Sep 17 00:00:00 2001 From: gitoleg Date: Fri, 13 Dec 2024 17:14:52 +0300 Subject: [PATCH 6/6] typo fixed --- clang/lib/CIR/CodeGen/CIRGenCall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index ebf30c7d9fe6..a7e79f713b68 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -901,7 +901,7 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo, assert(Results.size() <= 1 && "multiple returns NYI"); assert(Results[0].getType() == RetCIRTy && "Bitcast support NYI"); - mlir::Region *region region = builder.getBlock()->getParent(); + mlir::Region *region = builder.getBlock()->getParent(); if (region != theCall->getParentRegion()) { Address DestPtr = ReturnValue.getValue();