Skip to content

Commit 2a4e0ff

Browse files
committed
IRGen: Don't use relative pointers for value witness tables under relative procotol witness tables mode
1 parent 3fd895a commit 2a4e0ff

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

lib/IRGen/GenOpaque.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,25 +334,34 @@ Address irgen::slotForLoadOfOpaqueWitness(IRGenFunction &IGF,
334334
/// Load a specific witness from a known table. The result is
335335
/// always an i8*.
336336
llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF,
337+
bool isProtocolWitness,
337338
llvm::Value *table,
338339
WitnessIndex index,
339340
llvm::Value **slotPtr) {
340-
auto isRelativeTable = IGF.IGM.IRGen.Opts.UseRelativeProtocolWitnessTables;
341+
// Is this is a load of a relative protocol witness table entry.
342+
auto isRelativeTable = IGF.IGM.IRGen.Opts.UseRelativeProtocolWitnessTables &&
343+
isProtocolWitness;
344+
341345
auto slot = slotForLoadOfOpaqueWitness(IGF, table, index, isRelativeTable);
342346
if (slotPtr) *slotPtr = slot.getAddress();
347+
343348
if (isRelativeTable) {
344349
return IGF.emitLoadOfRelativePointer(slot, false, IGF.IGM.Int8Ty);
345350
}
351+
346352
return IGF.emitInvariantLoad(slot);
347353
}
348354

349355
/// Load a specific witness from a known table. The result is
350356
/// always an i8*.
351357
llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF,
358+
bool isProtocolWitness,
352359
llvm::Value *table,
353360
llvm::Value *index,
354361
llvm::Value **slotPtr) {
355362
assert(table->getType() == IGF.IGM.WitnessTablePtrTy);
363+
assert(!isProtocolWitness &&
364+
"This function does not yet support relative protocol witnesses");
356365

357366
// GEP to the appropriate index.
358367
llvm::Value *slot =
@@ -438,7 +447,8 @@ static FunctionPointer emitLoadOfValueWitnessFunction(IRGenFunction &IGF,
438447

439448
llvm::Value *slot;
440449
llvm::Value *witness =
441-
emitInvariantLoadOfOpaqueWitness(IGF, table, windex, &slot);
450+
emitInvariantLoadOfOpaqueWitness(IGF, /*isProtocolWitness*/false, table,
451+
windex, &slot);
442452
auto label = getValueWitnessLabel(index);
443453
auto signature = IGF.IGM.getValueWitnessSignature(index);
444454

lib/IRGen/GenOpaque.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ namespace irgen {
5252
/// The load is marked invariant. This should not be used in contexts where
5353
/// the referenced witness table is still undergoing initialization.
5454
llvm::Value *emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF,
55+
bool isProtocolWitness,
5556
llvm::Value *table,
5657
WitnessIndex index,
5758
llvm::Value **slot = nullptr);
@@ -62,6 +63,7 @@ namespace irgen {
6263
/// The load is marked invariant. This should not be used in contexts where
6364
/// the referenced witness table is still undergoing initialization.
6465
llvm::Value *emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF,
66+
bool isProtocolWitness,
6567
llvm::Value *table,
6668
llvm::Value *index,
6769
llvm::Value **slot = nullptr);

lib/IRGen/GenProto.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,7 +2634,8 @@ llvm::Value *irgen::loadParentProtocolWitnessTable(IRGenFunction &IGF,
26342634
auto &IGM = IGF.IGM;
26352635
if (!IGM.IRGen.Opts.UseRelativeProtocolWitnessTables) {
26362636
auto baseWTable =
2637-
emitInvariantLoadOfOpaqueWitness(IGF, wtable, index);
2637+
emitInvariantLoadOfOpaqueWitness(IGF,/*isProtocolWitness*/true, wtable,
2638+
index);
26382639
return baseWTable;
26392640
}
26402641
auto &Builder = IGF.Builder;
@@ -2659,7 +2660,8 @@ llvm::Value *irgen::loadParentProtocolWitnessTable(IRGenFunction &IGF,
26592660

26602661
Builder.emitBlock(isNotCondBB);
26612662
auto baseWTable2 =
2662-
emitInvariantLoadOfOpaqueWitness(IGF, wtable, index);
2663+
emitInvariantLoadOfOpaqueWitness(IGF,/*isProtocolWitness*/true, wtable,
2664+
index);
26632665
baseWTable2 = IGF.Builder.CreateBitCast(baseWTable2,
26642666
IGF.IGM.WitnessTablePtrTy);
26652667
Builder.CreateBr(endBB);
@@ -2677,7 +2679,8 @@ llvm::Value *irgen::loadConditionalConformance(IRGenFunction &IGF,
26772679

26782680
auto &IGM = IGF.IGM;
26792681
if (!IGM.IRGen.Opts.UseRelativeProtocolWitnessTables) {
2680-
return emitInvariantLoadOfOpaqueWitness(IGF, wtable, index);
2682+
return emitInvariantLoadOfOpaqueWitness(IGF, /*isProtocolWitness*/true,
2683+
wtable, index);
26812684
}
26822685

26832686
auto &Builder = IGF.Builder;

test/IRGen/relative_protocol_witness_table.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
// REQUIRES: CPU=x86_64 || CPU=arm64
44
// UNSUPPORTED: CPU=arm64e
55

6+
func testVWT<T>(_ t: T) {
7+
var local = t
8+
}
9+
610
protocol FuncOnly {
711
func a()
812
func b()
@@ -185,6 +189,18 @@ func instantiate_conditional_conformance_2nd<T>(_ t : T) where T: Sub, T.S == T
185189
// CHECK-SAME: i64 ptrtoint (i32* getelementptr inbounds ([4 x i32], [4 x i32]* @"$s1A17ConditionalStructVyxGAA20WithAssocConformanceA2A8FuncOnlyRzAA5InitPRzlWP", i32 0, i32 3) to i64)) to i32)
186190
// CHECK-SAME: ], align 8
187191

192+
// Make sure value witness table lookup is done right.
193+
194+
// CHECK: define{{.*}} swiftcc void @"$s1A7testVWTyyxlF"(%swift.opaque* {{.*}}, %swift.type* [[T:%.*]])
195+
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T]] to i8***
196+
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
197+
// CHECK: [[VWT_PTR:%.*]] = load i8**, i8*** [[VWT_ADDR]]
198+
// CHECK: [[T1:%.*]] = getelementptr inbounds i8*, i8** [[VWT_PTR]], i32 2
199+
// CHECK: [[T2:%.*]] = load i8*, i8** [[T1]]
200+
// CHECK: [[T3:%.*]] = bitcast i8* [[T2]] to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)*
201+
// CHECK: call %swift.opaque* [[T3]](%swift.opaque* {{.*}}, %swift.opaque* {{.*}}, %swift.type* [[T]])
202+
203+
188204
// Simple witness entry access.
189205

190206
// CHECK: define{{.*}} swiftcc void @"$s1A14requireWitnessyyxAA8FuncOnlyRzlF"(%swift.opaque* noalias nocapture {{%.*}}, %swift.type* {{%.*}}, i8** [[PWT:%.*]])

0 commit comments

Comments
 (0)