diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def index ff7327bf7de..4e7ac997acf 100644 --- a/include/swift/AST/Builtins.def +++ b/include/swift/AST/Builtins.def @@ -719,9 +719,6 @@ BUILTIN_MISC_OPERATION(IsNegative, "isNegative", "n", Special) /// (_ value: Builtin.IntLiteral, _ index: Builtin.Word) -> Builtin.Word BUILTIN_MISC_OPERATION(WordAtIndex, "wordAtIndex", "n", Special) -/// zeroInitializer has type () -> T -BUILTIN_MISC_OPERATION(ZeroInitializer, "zeroInitializer", "n", Special) - /// once has type (Builtin.RawPointer, (Builtin.RawPointer) -> ()) BUILTIN_MISC_OPERATION(Once, "once", "", Special) /// onceWithContext has type (Builtin.RawPointer, (Builtin.RawPointer) -> (), Builtin.RawPointer) @@ -842,6 +839,10 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(Strideof, "strideof", "n", Special) /// Alignof has type T.Type -> Int BUILTIN_MISC_OPERATION_WITH_SILGEN(Alignof, "alignof", "n", Special) +/// zeroInitializer has type () -> T, but the SIL builtin has its +/// own rules. +BUILTIN_MISC_OPERATION_WITH_SILGEN(ZeroInitializer, "zeroInitializer", "n", Special) + // getCurrentExecutor: () async -> Builtin.Executor? // // Retrieve the SerialExecutorRef on which the current asynchronous diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h index 59781fecccd..d991e4f904f 100644 --- a/include/swift/SIL/SILBuilder.h +++ b/include/swift/SIL/SILBuilder.h @@ -2422,6 +2422,16 @@ public: valueType, paramType)); } + /// Create a zero-initialized value of the given (loadable) type. + /// + /// This is currently only expected to be used in narrow situations + /// involving bridging and only makes a best effort attempt. + SILValue createZeroInitValue(SILLocation loc, SILType loweredTy); + + /// Zero-initialize an object in memory of the given type (which may + /// or may not be loadable). + BuiltinInst *createZeroInitAddr(SILLocation loc, SILValue addr); + //===--------------------------------------------------------------------===// // Unchecked cast helpers //===--------------------------------------------------------------------===// diff --git a/lib/IRGen/GenBuiltin.cpp b/lib/IRGen/GenBuiltin.cpp index b6fb2359765..d23852cd6a9 100644 --- a/lib/IRGen/GenBuiltin.cpp +++ b/lib/IRGen/GenBuiltin.cpp @@ -1327,18 +1327,18 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin, } if (Builtin.ID == BuiltinValueKind::ZeroInitializer) { - // Build a zero initializer of the result type. - auto valueTy = getLoweredTypeAndTypeInfo(IGF.IGM, - substitutions.getReplacementTypes()[0]); - if (args.size() > 0) { + auto valueType = argTypes[0]; + auto &valueTI = IGF.IGM.getTypeInfo(valueType); + // `memset` the memory addressed by the argument. auto address = args.claimNext(); - IGF.Builder.CreateMemSet(valueTy.second.getAddressForPointer(address), + IGF.Builder.CreateMemSet(valueTI.getAddressForPointer(address), llvm::ConstantInt::get(IGF.IGM.Int8Ty, 0), - valueTy.second.getSize(IGF, argTypes[0])); + valueTI.getSize(IGF, valueType)); } else { - auto schema = valueTy.second.getSchema(); + auto &resultTI = cast(IGF.IGM.getTypeInfo(resultType)); + auto schema = resultTI.getSchema(); for (auto &elt : schema) { out.add(llvm::Constant::getNullValue(elt.getScalarType())); } diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp index 750c5985b80..11adbef00f0 100644 --- a/lib/IRGen/LoadableByAddress.cpp +++ b/lib/IRGen/LoadableByAddress.cpp @@ -4165,9 +4165,9 @@ protected: BuiltinValueKind::ZeroInitializer) { auto build = assignment.getBuilder(++bi->getIterator()); auto newAddr = assignment.createAllocStack(bi->getType()); + build.createZeroInitAddr(bi->getLoc(), newAddr); assignment.mapValueToAddress(origValue, newAddr); - build.createStore(bi->getLoc(), origValue, newAddr, - StoreOwnershipQualifier::Unqualified); + assignment.markForDeletion(bi); } else { singleValueInstructionFallback(bi); } diff --git a/lib/SIL/IR/SILBuilder.cpp b/lib/SIL/IR/SILBuilder.cpp index 1efe34030dc..ce9cc84a3ec 100644 --- a/lib/SIL/IR/SILBuilder.cpp +++ b/lib/SIL/IR/SILBuilder.cpp @@ -805,6 +805,26 @@ CheckedCastBranchInst *SILBuilder::createCheckedCastBranch( target2Count, forwardingOwnershipKind)); } +BuiltinInst *SILBuilder::createZeroInitAddr(SILLocation loc, SILValue addr) { + assert(addr->getType().isAddress()); + auto &C = getASTContext(); + auto zeroInit = getBuiltinValueDecl(C, C.getIdentifier("zeroInitializer")); + return createBuiltin(loc, zeroInit->getBaseIdentifier(), + SILType::getEmptyTupleType(C), + SubstitutionMap(), + addr); +} + +SILValue SILBuilder::createZeroInitValue(SILLocation loc, SILType loweredTy) { + assert(loweredTy.isObject()); + auto &C = getASTContext(); + auto zeroInit = getBuiltinValueDecl(C, C.getIdentifier("zeroInitializer")); + return createBuiltin(loc, zeroInit->getBaseIdentifier(), + loweredTy, + SubstitutionMap(), + {}); +} + void SILBuilderWithScope::insertAfter(SILInstruction *inst, function_ref func) { if (isa(inst)) { diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index f92b17bdf9d..83a072f76a8 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -1009,6 +1009,11 @@ public: #define requireAddressType(type, value, valueDescription) \ _requireAddressType(value, valueDescription, #type) + void requireVoidObjectType(SILType type, const Twine &valueDescription) { + _require(type.isObject() && type.isVoid(), + valueDescription + " must be a scalar of type ()"); + } + template typename CanTypeWrapperTraits::type _forbidObjectType(SILType type, const Twine &valueDescription, @@ -2375,6 +2380,23 @@ public: auto builtinKind = BI->getBuiltinKind(); auto arguments = BI->getArguments(); + if (builtinKind == BuiltinValueKind::ZeroInitializer) { + require(!BI->getSubstitutions(), + "zeroInitializer has no generic arguments as a SIL builtin"); + if (arguments.size() == 0) { + require(!fnConv.useLoweredAddresses() + || BI->getType().isLoadable(*BI->getFunction()), + "scalar zeroInitializer must have a loadable result type"); + } else { + require(arguments.size() == 1, + "zeroInitializer cannot have multiple arguments"); + require(arguments[0]->getType().isAddress(), + "zeroInitializer argument must have address type"); + requireVoidObjectType(BI->getType(), + "result of zeroInitializer"); + } + } + // Check that 'getCurrentAsyncTask' only occurs within an async function. if (builtinKind == BuiltinValueKind::GetCurrentAsyncTask) { require(F.isAsync(), diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 59af48470e0..424fc38023f 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -1985,8 +1985,9 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) { auto param = completionTy->getParameters()[i]; auto paramTy = param.getSILStorageInterfaceType(); if (paramTy.isTrivial(F)) { - // If it's trivial, the value passed doesn't matter. - completionHandlerArgs.push_back(SILUndef::get(&F, paramTy)); + // If it's trivial, pass a zero value of whatever the type is. + auto zero = B.createZeroInitValue(loc, paramTy); + completionHandlerArgs.push_back(zero); } else { // If it's not trivial, it must be a nullable class type. Pass // nil. diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp index dc6b002d947..a5456dca65c 100644 --- a/lib/SILGen/SILGenBuiltin.cpp +++ b/lib/SILGen/SILGenBuiltin.cpp @@ -2097,6 +2097,26 @@ static ManagedValue emitBuiltinAddressOfRawLayout(SILGenFunction &SGF, return ManagedValue::forObjectRValueWithoutOwnership(bi); } +static ManagedValue emitBuiltinZeroInitializer(SILGenFunction &SGF, + SILLocation loc, + SubstitutionMap subs, + ArrayRef args, + SGFContext C) { + auto valueType = subs.getReplacementTypes()[0]->getCanonicalType(); + auto &valueTL = SGF.getTypeLowering(valueType); + auto loweredValueTy = valueTL.getLoweredType().getObjectType(); + + if (valueTL.isLoadable() || + !SGF.F.getConventions().useLoweredAddresses()) { + auto value = SGF.B.createZeroInitValue(loc, loweredValueTy); + return SGF.emitManagedRValueWithCleanup(value, valueTL); + } + + SILValue valueAddr = SGF.getBufferForExprResult(loc, loweredValueTy, C); + SGF.B.createZeroInitAddr(loc, valueAddr); + return SGF.manageBufferForExprResult(valueAddr, valueTL, C); +} + static ManagedValue emitBuiltinEmplace(SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs, @@ -2129,15 +2149,7 @@ static ManagedValue emitBuiltinEmplace(SILGenFunction &SGF, // Aside from providing a modicum of predictability if the memory isn't // actually initialized, this also serves to communicate to DI that the memory // is considered initialized from this point. - auto zeroInit = getBuiltinValueDecl(Ctx, - Ctx.getIdentifier("zeroInitializer")); - SGF.B.createBuiltin(loc, zeroInit->getBaseIdentifier(), - SILType::getEmptyTupleType(Ctx), - SubstitutionMap::get(zeroInit->getInnermostDeclContext() - ->getGenericSignatureOfContext(), - {resultASTTy}, - LookUpConformanceInModule()), - buffer); + SGF.B.createZeroInitAddr(loc, buffer); SILValue bufferPtr = SGF.B.createAddressToPointer(loc, buffer, SILType::getPrimitiveObjectType(SGF.getASTContext().TheRawPointerType), diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp index e369eedc58f..5c0586bd1fc 100644 --- a/lib/SILGen/SILGenConstructor.cpp +++ b/lib/SILGen/SILGenConstructor.cpp @@ -739,15 +739,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) { if (nominal->getAttrs().hasAttribute()) { // Raw memory is not directly decomposable, but we still want to mark // it as initialized. Use a zero initializer. - auto &C = ctor->getASTContext(); - auto zeroInit = getBuiltinValueDecl(C, C.getIdentifier("zeroInitializer")); - B.createBuiltin(ctor, zeroInit->getBaseIdentifier(), - SILType::getEmptyTupleType(C), - SubstitutionMap::get(zeroInit->getInnermostDeclContext() - ->getGenericSignatureOfContext(), - {selfDecl->getTypeInContext()}, - LookUpConformanceInModule()), - selfLV.getLValueAddress()); + B.createZeroInitAddr(ctor, selfLV.getLValueAddress()); } else if (isa(nominal) && lowering.getLoweredType().isMoveOnly() && nominal->getStoredProperties().empty()) { diff --git a/test/ClangImporter/objc_init_blocks.swift b/test/ClangImporter/objc_init_blocks.swift index 29584f9ddec..18f31b1a336 100644 --- a/test/ClangImporter/objc_init_blocks.swift +++ b/test/ClangImporter/objc_init_blocks.swift @@ -7,7 +7,7 @@ // Make sure that the SIL ownership verifier passes. // UnsafeUnretainedBlockClass.init() // CHECK-LABEL: sil hidden @$s16objc_init_blocks26UnsafeUnretainedBlockClassCACycfc : $@convention(method) (@owned UnsafeUnretainedBlockClass) -> @owned UnsafeUnretainedBlockClass { -// CHECK: [[ZI:%.*]] = builtin "zeroInitializer"() : $objc_bool_block +// CHECK: [[ZI:%.*]] = builtin "zeroInitializer"() : $objc_bool_block // CHECK: store [[ZI]] to %{{.*}} : $*objc_bool_block // CHECK-LABEL: } // end sil function '$s16objc_init_blocks26UnsafeUnretainedBlockClassCACycfc' open class UnsafeUnretainedBlockClass { diff --git a/test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h b/test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h index 9e17a30ca89..15d4468ff8c 100644 --- a/test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h +++ b/test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h @@ -364,4 +364,8 @@ MAIN_ACTOR - (void)loadFloatWithCompletionHandler:(void (^)(float))completionHandler; @end +@protocol FailableFloatLoader +- (void)loadFloatOrThrowWithCompletionHandler:(void (^)(float, NSError* __nullable)) completionHandler; +@end + #pragma clang assume_nonnull end diff --git a/test/SILGen/objc_async.swift b/test/SILGen/objc_async.swift index f9731c5ea55..ab9b2af44fb 100644 --- a/test/SILGen/objc_async.swift +++ b/test/SILGen/objc_async.swift @@ -330,3 +330,33 @@ extension OptionalMemberLookups { func checkHotdogs(_ v: some HotdogCompetitor, _ timeLimit: NSObject) async throws -> String? { return try await v.pileOfHotdogsToEat(withLimit: timeLimit) } + +/// Issue 65199: pass zero-initialized completion handler arguments for the +/// normal result on the error path of an ObjC async thunk. +extension SlowServer: @retroactive FailableFloatLoader { + public func loadFloatOrThrow() async throws -> Float { + return 0 + } +} +// CHECK-LABEL: sil [ossa] @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKF : $@convention(method) @async (@guaranteed SlowServer) -> (Float, @error any Error) + +// CHECK-LABEL: sil private [thunk] [ossa] @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKFTo : $@convention(objc_method) (@convention(block) @Sendable (Float, Optional) -> (), SlowServer) -> () { +// CHECK: function_ref @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKFyyYacfU_To + +// CHECK-LABEL: sil shared [thunk] [ossa] @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKFyyYacfU_To : $@convention(thin) @Sendable @async (@convention(block) @Sendable (Float, Optional) -> (), SlowServer) -> () +// CHECK: [[BLOCK:%.*]] = copy_block +// CHECK: [[METHOD:%.*]] = function_ref @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKF : +// CHECK: try_apply [[METHOD]]({{%.*}}) : {{.*}}, normal bb1, error bb2 +// CHECK: bb1([[NORMAL_RESULT:%.*]] : $Float): +// CHECK-NEXT: [[BORROWED_BLOCK:%.*]] = begin_borrow [[BLOCK]] : +// CHECK-NEXT: [[NIL_NSERROR:%.*]] = enum $Optional, #Optional.none +// CHECK-NEXT: apply [[BORROWED_BLOCK]]([[NORMAL_RESULT]], [[NIL_NSERROR]]) +// CHECK: bb2([[ERROR_RESULT:%.*]] : @owned $any Error): +// CHECK-NEXT: [[BORROWED_BLOCK:%.*]] = begin_borrow [[BLOCK]] : +// CHECK-NEXT: // function_ref +// CHECK-NEXT: [[CONVERT_FN:%.*]] = function_ref +// CHECK-NEXT: [[NSERROR:%.*]] = apply [[CONVERT_FN]]([[ERROR_RESULT]]) +// CHECK-NEXT: [[SOME_NSERROR:%.*]] = enum $Optional, #Optional.some!enumelt, [[NSERROR]] : $NSError +// CHECK-NEXT: [[ZERO_FLOAT:%.*]] = builtin "zeroInitializer"() : $Float +// CHECK-NEXT: [[BORROWED_SOME_NSERROR:%.*]] = begin_borrow [[SOME_NSERROR]] : +// CHECK-NEXT: apply [[BORROWED_BLOCK]]([[ZERO_FLOAT]], [[BORROWED_SOME_NSERROR]]) diff --git a/test/SILOptimizer/mem-behavior.sil b/test/SILOptimizer/mem-behavior.sil index 0e2eab7be76..2a7b6483cfc 100644 --- a/test/SILOptimizer/mem-behavior.sil +++ b/test/SILOptimizer/mem-behavior.sil @@ -1289,18 +1289,18 @@ bb0(%0 : $*C, %1 : $*C, %2 : @owned $C): // CHECK-LABEL: @test_builtin_zeroInitializer // CHECK: PAIR #0. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %0 = alloc_stack // CHECK-NEXT: r=0,w=0 // CHECK: PAIR #1. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %1 = alloc_stack // CHECK-NEXT: r=0,w=1 sil @test_builtin_zeroInitializer : $@convention(thin) () -> () { bb0: %0 = alloc_stack $C %1 = alloc_stack $C - %2 = builtin "zeroInitializer"(%1 : $*C) : $() + %2 = builtin "zeroInitializer"(%1 : $*C) : $() %3 = apply undef(%1) : $@convention(thin) () -> @out C copy_addr [take] %1 to [init] %0 : $*C dealloc_stack %1 : $*C @@ -1312,18 +1312,18 @@ bb0: // CHECK-LABEL: @test_builtin_zeroInitializer_atomicload // CHECK: PAIR #0. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %0 = alloc_stack // CHECK-NEXT: r=0,w=0 // CHECK: PAIR #1. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %1 = alloc_stack // CHECK-NEXT: r=0,w=1 sil @test_builtin_zeroInitializer_atomicload : $@convention(thin) () -> Builtin.Int64 { bb0: %0 = alloc_stack $C %1 = alloc_stack $C - %2 = builtin "zeroInitializer"(%1 : $*C) : $() + %2 = builtin "zeroInitializer"(%1 : $*C) : $() %3 = apply undef(%1) : $@convention(thin) () -> @out C copy_addr [take] %1 to [init] %0 : $*C dealloc_stack %1 : $*C @@ -1336,18 +1336,18 @@ bb0: // CHECK-LABEL: @test_builtin_zeroInitializer_atomicstore // CHECK: PAIR #0. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %0 = alloc_stack // CHECK-NEXT: r=0,w=0 // CHECK: PAIR #1. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %1 = alloc_stack // CHECK-NEXT: r=0,w=1 sil @test_builtin_zeroInitializer_atomicstore : $@convention(thin) () -> () { bb0: %0 = alloc_stack $C %1 = alloc_stack $C - %2 = builtin "zeroInitializer"(%1 : $*C) : $() + %2 = builtin "zeroInitializer"(%1 : $*C) : $() %3 = apply undef(%1) : $@convention(thin) () -> @out C copy_addr [take] %1 to [init] %0 : $*C dealloc_stack %1 : $*C @@ -1362,18 +1362,18 @@ bb0: // CHECK-LABEL: @test_builtin_zeroInitializer_atomicrmw // CHECK: PAIR #0. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %0 = alloc_stack // CHECK-NEXT: r=0,w=0 // CHECK: PAIR #1. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %1 = alloc_stack // CHECK-NEXT: r=0,w=1 sil @test_builtin_zeroInitializer_atomicrmw : $@convention(thin) () -> (Builtin.Int64, Builtin.Int64) { bb0: %0 = alloc_stack $C %1 = alloc_stack $C - %2 = builtin "zeroInitializer"(%1 : $*C) : $() + %2 = builtin "zeroInitializer"(%1 : $*C) : $() %3 = apply undef(%1) : $@convention(thin) () -> @out C copy_addr [take] %1 to [init] %0 : $*C dealloc_stack %1 : $*C @@ -1389,18 +1389,18 @@ bb0: // CHECK-LABEL: @test_builtin_zeroInitializer_cmpxchg // CHECK: PAIR #0. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %0 = alloc_stack // CHECK-NEXT: r=0,w=0 // CHECK: PAIR #1. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %1 = alloc_stack // CHECK-NEXT: r=0,w=1 sil @test_builtin_zeroInitializer_cmpxchg : $@convention(thin) () -> (Builtin.Int64, Builtin.Int1) { bb0: %0 = alloc_stack $C %1 = alloc_stack $C - %2 = builtin "zeroInitializer"(%1 : $*C) : $() + %2 = builtin "zeroInitializer"(%1 : $*C) : $() %3 = apply undef(%1) : $@convention(thin) () -> @out C copy_addr [take] %1 to [init] %0 : $*C dealloc_stack %1 : $*C @@ -1414,18 +1414,18 @@ bb0: // CHECK-LABEL: @test_builtin_zeroInitializer_fence // CHECK: PAIR #0. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %0 = alloc_stack // CHECK-NEXT: r=0,w=0 // CHECK: PAIR #1. -// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) +// CHECK-NEXT: %2 = builtin "zeroInitializer"(%1 : $*C) // CHECK-NEXT: %1 = alloc_stack // CHECK-NEXT: r=0,w=1 sil @test_builtin_zeroInitializer_fence : $@convention(thin) () -> () { bb0: %0 = alloc_stack $C %1 = alloc_stack $C - %2 = builtin "zeroInitializer"(%1 : $*C) : $() + %2 = builtin "zeroInitializer"(%1 : $*C) : $() %3 = apply undef(%1) : $@convention(thin) () -> @out C copy_addr [take] %1 to [init] %0 : $*C dealloc_stack %1 : $*C diff --git a/test/SILOptimizer/moveonly_raw_layout.swift b/test/SILOptimizer/moveonly_raw_layout.swift index 18de20759f9..38cfcf5b705 100644 --- a/test/SILOptimizer/moveonly_raw_layout.swift +++ b/test/SILOptimizer/moveonly_raw_layout.swift @@ -20,7 +20,7 @@ struct Lock: ~Copyable { // CHECK-NEXT: sil{{.*}} @[[INIT:\$.*4LockV.*fC]] : init() { // CHECK-NOT: destroy_addr - // CHECK: builtin "zeroInitializer" + // CHECK: builtin "zeroInitializer"({{%.*}} : $*Lock) // CHECK-NOT: destroy_addr // CHECK: [[F:%.*]] = function_ref @init_lock // CHECK: apply [[F]]( diff --git a/test/SILOptimizer/stdlib/Cell.swift b/test/SILOptimizer/stdlib/Cell.swift index 31d4ced9c2c..fefc37fc93d 100644 --- a/test/SILOptimizer/stdlib/Cell.swift +++ b/test/SILOptimizer/stdlib/Cell.swift @@ -20,7 +20,7 @@ public struct Cell: ~Copyable { // CHECK-LABEL: sil {{.*}} @$s4CellAAVAARi_zrlEyAByxGxcfC : $@convention(method) (@in T, @thin Cell.Type) -> @out Cell { // CHECK: bb0({{%.*}} : $*Cell, [[VALUE:%.*]] : $*T, {{%.*}} : $@thin Cell.Type): - // CHECK: {{%.*}} = builtin "zeroInitializer">([[SELF:%.*]] : $*Cell) : $() + // CHECK: {{%.*}} = builtin "zeroInitializer"([[SELF:%.*]] : $*Cell) : $() // CHECK-NEXT: [[RAW_LAYOUT_ADDR:%.*]] = builtin "addressOfRawLayout">([[SELF]] : $*Cell) : $Builtin.RawPointer // CHECK-NEXT: [[POINTER:%.*]] = struct $UnsafeMutablePointer ([[RAW_LAYOUT_ADDR]] : $Builtin.RawPointer) // Calling 'UnsafeMutablePointer.initialize(to:)' diff --git a/test/SILOptimizer/templvalueopt.sil b/test/SILOptimizer/templvalueopt.sil index 517a787aef4..fd4c42fde5e 100644 --- a/test/SILOptimizer/templvalueopt.sil +++ b/test/SILOptimizer/templvalueopt.sil @@ -254,13 +254,13 @@ bb0(%0 : $*T, %1 : $*T): // CHECK-LABEL: sil @optimize_builtin_zeroInitialize : {{.*}} { // CHECK: bb0([[RET_ADDR:%[^,]+]] : -// CHECK: builtin "zeroInitializer"([[RET_ADDR]] : $*T) : $() +// CHECK: builtin "zeroInitializer"([[RET_ADDR]] : $*T) : $() // CHECK: apply undef([[RET_ADDR]]) // CHECK-LABEL: } // end sil function 'optimize_builtin_zeroInitialize' sil @optimize_builtin_zeroInitialize : $@convention(thin) () -> @out T { bb0(%ret_addr : $*T): %temporary = alloc_stack [lexical] $T - builtin "zeroInitializer"(%temporary : $*T) : $() + builtin "zeroInitializer"(%temporary : $*T) : $() apply undef(%temporary) : $@convention(thin) () -> @out T copy_addr [take] %temporary to [init] %ret_addr : $*T dealloc_stack %temporary : $*T