Skip to content

Commit 8458226

Browse files
authored
Merge pull request #84779 from kavon/opaque-values/unreachable-expr-rdar162239557
SILGen: revise emission of UnreachableExpr
2 parents f2188f6 + 1e28b0a commit 8458226

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,19 +2637,31 @@ RValue RValueEmitter::visitUnderlyingToOpaqueExpr(UnderlyingToOpaqueExpr *E,
26372637
}
26382638

26392639
RValue RValueEmitter::visitUnreachableExpr(UnreachableExpr *E, SGFContext C) {
2640-
// Emit the expression, followed by an unreachable. To produce a value of
2641-
// arbitrary type, we emit a temporary allocation, with the use of the
2642-
// allocation in the unreachable block. The SILOptimizer will eliminate both
2643-
// the unreachable block and unused allocation.
2640+
// Emit the expression, followed by an unreachable.
26442641
SGF.emitIgnoredExpr(E->getSubExpr());
2642+
SGF.B.createUnreachable(E);
2643+
2644+
// Continue code generation in a block with no predecessors.
2645+
// Whatever code is emitted here is guaranteed to be removed by SIL passes.
2646+
SGF.B.emitBlock(SGF.createBasicBlock());
26452647

2648+
// Since the type is uninhabited, use a SILUndef of so that we can return
2649+
// some sort of RValue from this API.
26462650
auto &lowering = SGF.getTypeLowering(E->getType());
2647-
auto resultAddr = SGF.emitTemporaryAllocation(E, lowering.getLoweredType());
2651+
auto loweredTy = lowering.getLoweredType();
2652+
auto undef = SILUndef::get(SGF.F, loweredTy);
26482653

2649-
SGF.B.createUnreachable(E);
2650-
SGF.B.emitBlock(SGF.createBasicBlock());
2654+
// Create an alloc initialized with contents from the undefined addr type.
2655+
// It seems pack addresses do not satisfy isPlusOneOrTrivial, so we need an
2656+
// actual allocation.
2657+
if (loweredTy.isAddress()) {
2658+
auto resultAddr = SGF.emitTemporaryAllocation(E, loweredTy);
2659+
SGF.emitSemanticStore(E, undef, resultAddr, lowering, IsInitialization);
2660+
return RValue(SGF, E, SGF.emitManagedRValueWithCleanup(resultAddr));
2661+
}
26512662

2652-
return RValue(SGF, E, SGF.emitManagedRValueWithCleanup(resultAddr));
2663+
// Otherwise, if it's not an address, just emit the undef value itself.
2664+
return RValue(SGF, E, ManagedValue::forRValueWithoutOwnership(undef));
26532665
}
26542666

26552667
VarargsInfo Lowering::emitBeginVarargs(SILGenFunction &SGF, SILLocation loc,

test/SILGen/unreachable_expr.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %target-swift-emit-silgen %s -verify -sil-verify-all | %FileCheck %s --check-prefixes CHECK,REG
2+
// RUN: %target-swift-emit-silgen %s -verify -sil-verify-all -enable-sil-opaque-values | %FileCheck %s --check-prefixes CHECK,OV
3+
4+
// CHECK-LABEL: sil{{.*}} [ossa] @{{.*}}uninhabited_generic{{.*}}
5+
// CHECK: [[NEVER:%[^,]+]] = apply {{.*}} -> Never
6+
// CHECK-NEXT: ignored_use [[NEVER]]
7+
// CHECK-NEXT: unreachable
8+
//
9+
// CHECK: bb1:
10+
// CHECK-NOT: Preds
11+
12+
// Without opaque values, take from an undef address,
13+
// through a temporary alloc, to eventually the out-parameter %0
14+
// REG-NEXT: [[BOGUS_ALLOC:%.*]] = alloc_stack $T
15+
// REG-NEXT: copy_addr [take] undef to [init] [[BOGUS_ALLOC]]
16+
// REG-NEXT: copy_addr [take] [[BOGUS_ALLOC]] to [init] %0
17+
18+
// With opaque values, simply return the undef value
19+
// OV-NEXT: return undef : $T
20+
func uninhabited_generic<T>() -> T { fatalError("todo") }

test/SILGen/variadic-generic-tuples.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,16 @@ func convertVoidPayloads() {
430430
convertPayloads(as: Void.self)
431431
}
432432

433+
// CHECK-LABEL: sil{{.*}} [ossa] @{{.*}}convertPayloads{{.*}} :
434+
// CHECK: ignored_use {{.*}}
435+
// CHECK-NEXT: unreachable
436+
//
437+
// CHECK: bb1:
438+
// CHECK-NOT: Preds
439+
// CHECK: [[BOGUS_ALLOC:%.*]] = alloc_stack $(repeat each Value)
440+
// CHECK-NEXT: copy_addr [take] undef to [init] [[BOGUS_ALLOC]]
441+
//
442+
// CHECK: = tuple_pack_element_addr {{.*}} of [[BOGUS_ALLOC]]
433443
func convertPayloads<each Value>(as valueTypes: repeat (each Value).Type) -> (repeat each Value) {
434444
fatalError()
435445
}

0 commit comments

Comments
 (0)