Skip to content

Commit c711181

Browse files
Merge pull request #21256 from aschwaighofer/irgen_conditionally_test_weak_enum_cases
IRGen: Conditionally test weakly linked enum cases
2 parents b701dc4 + 5ae00ee commit c711181

File tree

3 files changed

+68
-7
lines changed

3 files changed

+68
-7
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5412,13 +5412,50 @@ namespace {
54125412
enumAddr);
54135413
}
54145414

5415+
llvm::Value *testResilientTag(IRGenFunction &IGF, llvm::Value *tag,
5416+
EnumElementDecl *Case) const {
5417+
auto &C = IGM.getLLVMContext();
5418+
5419+
// If the enum case is weakly linked check the address of the case
5420+
// first.
5421+
llvm::BasicBlock *conditionalBlock = nullptr;
5422+
llvm::BasicBlock *afterConditionalBlock = nullptr;
5423+
llvm::BasicBlock *beforeNullPtrCheck = nullptr;
5424+
if (Case->isWeakImported(IGM.getSwiftModule())) {
5425+
beforeNullPtrCheck = IGF.Builder.GetInsertBlock();
5426+
auto address = IGM.getAddrOfEnumCase(Case, NotForDefinition);
5427+
conditionalBlock = llvm::BasicBlock::Create(C);
5428+
afterConditionalBlock = llvm::BasicBlock::Create(C);
5429+
auto *addressVal =
5430+
IGF.Builder.CreatePtrToInt(address.getAddress(), IGM.IntPtrTy);
5431+
auto isNullPtr = IGF.Builder.CreateICmpEQ(
5432+
addressVal, llvm::ConstantInt::get(IGM.IntPtrTy, 0));
5433+
IGF.Builder.CreateCondBr(isNullPtr, afterConditionalBlock,
5434+
conditionalBlock);
5435+
}
5436+
if (conditionalBlock)
5437+
IGF.Builder.emitBlock(conditionalBlock);
5438+
5439+
// Check the tag.
5440+
auto tagVal = loadResilientTagIndex(IGF, Case);
5441+
auto matchesTag = IGF.Builder.CreateICmpEQ(tag, tagVal);
5442+
if (conditionalBlock) {
5443+
IGF.Builder.CreateBr(afterConditionalBlock);
5444+
IGF.Builder.emitBlock(afterConditionalBlock);
5445+
auto phi = IGF.Builder.CreatePHI(IGM.Int1Ty, 2);
5446+
phi->addIncoming(IGF.Builder.getInt1(false), beforeNullPtrCheck);
5447+
phi->addIncoming(matchesTag, conditionalBlock);
5448+
matchesTag = phi;
5449+
}
5450+
return matchesTag;
5451+
}
5452+
54155453
llvm::Value *
54165454
emitIndirectCaseTest(IRGenFunction &IGF, SILType T,
54175455
Address enumAddr,
54185456
EnumElementDecl *Case) const override {
54195457
llvm::Value *tag = emitGetEnumTagCall(IGF, T, enumAddr);
5420-
llvm::Value *expectedTag = loadResilientTagIndex(IGF, Case);
5421-
return IGF.Builder.CreateICmpEQ(tag, expectedTag);
5458+
return testResilientTag(IGF, tag, Case);
54225459
}
54235460

54245461
void emitIndirectSwitch(IRGenFunction &IGF,
@@ -5453,8 +5490,8 @@ namespace {
54535490
if (continuationBB)
54545491
IGF.Builder.emitBlock(continuationBB);
54555492

5456-
auto tagVal = loadResilientTagIndex(IGF, elt.decl);
5457-
auto matchesTag = IGF.Builder.CreateICmpEQ(tag, tagVal);
5493+
// Check the tag.
5494+
auto matchesTag = testResilientTag(IGF, tag, elt.decl);
54585495

54595496
// If we are not the last block create a continuation block.
54605497
if (++numCasesEmitted < dests.size())

test/IRGen/weak_import_native.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,30 @@ public func test_not_hoist_weakly_linked4() {
230230
var _ = One(elt:(ResilientStruct(), 1))
231231
}
232232
}
233+
234+
// CHECK-DAG-LABEL: define{{.*}} @"$s18weak_import_native29test_weakly_linked_enum_cases1eSi0a1_b1_C7_helper1EO_t
235+
// CHECK: [[TAG:%.*]] = call i32 %getEnumTag(
236+
// CHECK: [[STRONG_CASE:%.*]] = load i32, i32* @"$s25weak_import_native_helper1EO6strongyA2CmFWC"
237+
// CHECK: [[IS_STRONG:%.*]] = icmp eq i32 [[TAG]], [[STRONG_CASE]]
238+
// CHECK: br i1 [[IS_STRONG]], label %[[BB0:[0-9]+]], label %[[BB1:[0-9]+]]
239+
//
240+
// CHECK: <label>:[[BB1]]:
241+
// CHECK: br i1 icmp eq ({{.*}} ptrtoint (i32* @"$s25weak_import_native_helper1EO0A0yA2CmFWC" to {{.*}}), {{.*}} 0), label %[[BB2:[0-9]+]], label %[[BB3:[0-9]+]]
242+
//
243+
// CHECK:; <label>:[[BB3]]:
244+
// CHECK: [[WEAK_CASE:%.*]] = load i32, i32* @"$s25weak_import_native_helper1EO0A0yA2CmFWC"
245+
// CHECK: [[IS_WEAK:%.*]] = icmp eq i32 [[TAG]], [[WEAK_CASE]]
246+
// CHECK: br label %21
247+
//
248+
// CHECK:; <label>:[[BB2]]:
249+
// CHECK: = phi i1 [ false, %[[BB1]] ], [ [[IS_WEAK]], %[[BB3]] ]
250+
public func test_weakly_linked_enum_cases(e: E) -> Int {
251+
switch e {
252+
case .strong:
253+
return 1
254+
case .weak:
255+
return 2
256+
default:
257+
return 3
258+
}
259+
}

validation-test/Evolution/test_backward_deploy_enum.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
import StdlibUnittest
55
import backward_deploy_enum
66

7-
// <rdar://problem/46438568>
8-
// REQUIRES: rdar46438568
9-
107
var BackwardDeployEnumTest = TestSuite("BackwardDeployEnum")
118

129
func checkIt(_ e: ResilientEnum) -> Int {

0 commit comments

Comments
 (0)