From cc3038dcf630b3daa3e0c636a0e6933f1d8c03e4 Mon Sep 17 00:00:00 2001 From: Nate Chandler Date: Thu, 20 Jul 2023 12:33:45 -0700 Subject: [PATCH 1/2] [OpaqueValues] Transforms emit addr-only loads. In opaque values mode, when transforming, load address even when their type is address-only. --- lib/SILGen/SILGenPoly.cpp | 2 +- test/SILGen/Inputs/opaque_values_cxx.h | 3 +++ test/SILGen/opaque_values_cxx.swift | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/SILGen/Inputs/opaque_values_cxx.h create mode 100644 test/SILGen/opaque_values_cxx.swift diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index c2cff48ad0ace..6ec1119ebe88d 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -371,7 +371,7 @@ ManagedValue Transform::transform(ManagedValue v, // expect this. if (v.getType().isAddress()) { auto &inputTL = SGF.getTypeLowering(v.getType()); - if (!inputTL.isAddressOnly()) { + if (!inputTL.isAddressOnly() || !SGF.silConv.useLoweredAddresses()) { v = emitManagedLoad(SGF, Loc, v, inputTL); } } diff --git a/test/SILGen/Inputs/opaque_values_cxx.h b/test/SILGen/Inputs/opaque_values_cxx.h new file mode 100644 index 0000000000000..4b357220c799d --- /dev/null +++ b/test/SILGen/Inputs/opaque_values_cxx.h @@ -0,0 +1,3 @@ +#include + +using VectorOfU32 = std::vector; diff --git a/test/SILGen/opaque_values_cxx.swift b/test/SILGen/opaque_values_cxx.swift new file mode 100644 index 0000000000000..3ef5d9897ee05 --- /dev/null +++ b/test/SILGen/opaque_values_cxx.swift @@ -0,0 +1,15 @@ +// RUN: %target-swift-emit-silgen -enable-sil-opaque-values -Xllvm -sil-full-demangle -cxx-interoperability-mode=swift-5.9 -import-objc-header %S/Inputs/opaque_values_cxx.h -primary-file %s | %FileCheck %s --check-prefix=CHECK + +import Cxx + +// CHECK-LABEL: sil {{.*}}[ossa] @$sSo3stdO{{(3__1O)?}}0042vectorUInt32allocatorUInt32_mzFHjGjjqraEeaV3Cxx0B8SequenceSCA{{.*}}P13__beginUnsafe11RawIteratorQzyFTW : {{.*}} { +// CHECK: bb0([[VECTOR_ADDR:%[^,]+]] : +// CHECK: [[VECTOR:%[^,]+]] = load_borrow [[VECTOR_ADDR]] +// CHECK: [[BEGIN_FN:%[^,]+]] = function_ref +// CHECK: [[BEGIN:%[^,]+]] = apply [[BEGIN_FN]]([[VECTOR]]) +// CHECK: end_borrow [[VECTOR]] +// CHECK: return [[BEGIN]] +// CHECK-LABEL: } // end sil function '$sSo3stdO{{(3__1O)?}}0042vectorUInt32allocatorUInt32_mzFHjGjjqraEeaV3Cxx0B8SequenceSCA{{.*}}P13__beginUnsafe11RawIteratorQzyFTW' +func test_cxx_vector_uint32t_iterate(_ n: Int, _ vectorOfU32: VectorOfU32) { + for x in vectorOfU32 {} +} From 51ff57856d4b344dec87e9cb64a5b9101f2db2e1 Mon Sep 17 00:00:00 2001 From: Nate Chandler Date: Thu, 20 Jul 2023 12:58:52 -0700 Subject: [PATCH 2/2] [OpaqueValues] Don't emit temporary in one case. When creating a foreign-to-native thunk, create a temporary when the foreign convention is indirect-non-inout only when using lowered addresses. --- lib/SILGen/SILGenBridging.cpp | 8 +++++--- test/SILGen/opaque_values_cxx.swift | 11 +++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 26685ac79c879..aed4d9498d615 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -2242,13 +2242,15 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) { auto bridged = emitNativeToBridgedValue(fd, param, nativeFormalType, foreignFormalType, foreignLoweredTy); - if (foreignParam.getConvention() == ParameterConvention::Indirect_In || - foreignParam.getConvention() == ParameterConvention::Indirect_In_Guaranteed) { + if (useLoweredAddresses() && + (foreignParam.getConvention() == ParameterConvention::Indirect_In || + foreignParam.getConvention() == + ParameterConvention::Indirect_In_Guaranteed)) { auto temp = emitTemporaryAllocation(fd, bridged.getType()); bridged.forwardInto(*this, fd, temp); bridged = emitManagedBufferWithCleanup(temp); } - + if (memberStatus.isInstance() && isSelf) { // Fill in the `self` space. args[memberStatus.getSelfIndex()] = bridged; diff --git a/test/SILGen/opaque_values_cxx.swift b/test/SILGen/opaque_values_cxx.swift index 3ef5d9897ee05..9a11b56c6fc1d 100644 --- a/test/SILGen/opaque_values_cxx.swift +++ b/test/SILGen/opaque_values_cxx.swift @@ -1,5 +1,10 @@ // RUN: %target-swift-emit-silgen -enable-sil-opaque-values -Xllvm -sil-full-demangle -cxx-interoperability-mode=swift-5.9 -import-objc-header %S/Inputs/opaque_values_cxx.h -primary-file %s | %FileCheck %s --check-prefix=CHECK +// TODO: Find the relevant mangled name instead of +// $sSo3stdO3__1O0020___wrap_iter__udAAdDaVSQSCSQ2eeoiySbx_xtFZTW for other +// platforms. +// REQUIRES: VENDOR=apple + import Cxx // CHECK-LABEL: sil {{.*}}[ossa] @$sSo3stdO{{(3__1O)?}}0042vectorUInt32allocatorUInt32_mzFHjGjjqraEeaV3Cxx0B8SequenceSCA{{.*}}P13__beginUnsafe11RawIteratorQzyFTW : {{.*}} { @@ -10,6 +15,12 @@ import Cxx // CHECK: end_borrow [[VECTOR]] // CHECK: return [[BEGIN]] // CHECK-LABEL: } // end sil function '$sSo3stdO{{(3__1O)?}}0042vectorUInt32allocatorUInt32_mzFHjGjjqraEeaV3Cxx0B8SequenceSCA{{.*}}P13__beginUnsafe11RawIteratorQzyFTW' +// CHECK-LABEL: sil {{.*}}[ossa] @$sSo3stdO{{(3__1O)?}}0020___wrap_iter__udAAdDaVSQSCSQ2eeoiySbx_xtFZTW : {{.*}} { +// CHECK: bb0([[LHS:%[^,]+]] : $std.__1.__wrap_iter<_>, [[RHS:%[^,]+]] : +// CHECK: [[CALLEE:%[^,]+]] = function_ref @$sSo2eeoiySbSo3stdO{{(3__1O)?}}0020___wrap_iter__udAAdDaV_AGtFTO +// CHECK: [[EQUAL:%[^,]+]] = apply [[CALLEE]]([[LHS]], [[RHS]]) +// CHECK: return [[EQUAL]] +// CHECK-LABEL: } // end sil function '$sSo3stdO{{(3__1O)?}}0020___wrap_iter__udAAdDaVSQSCSQ2eeoiySbx_xtFZTW' func test_cxx_vector_uint32t_iterate(_ n: Int, _ vectorOfU32: VectorOfU32) { for x in vectorOfU32 {} }