Skip to content

Commit 12e9aed

Browse files
committed
SILCombine: fix a crash when optimizing keypath-offset-of
Need to use the lowered type instead of the original type. rdar://103834325
1 parent 7a8eb60 commit 12e9aed

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,11 @@ bool SILCombiner::tryOptimizeKeypathOffsetOf(ApplyInst *AI,
343343

344344
KeyPathPattern *pattern = kp->getPattern();
345345
SubstitutionMap patternSubs = kp->getSubstitutions();
346-
CanType rootTy = pattern->getRootType().subst(patternSubs)->getCanonicalType();
347-
CanType parentTy = rootTy;
346+
SILFunction *f = AI->getFunction();
347+
SILType rootTy = f->getLoweredType(Lowering::AbstractionPattern::getOpaque(),
348+
pattern->getRootType().subst(patternSubs)->getCanonicalType());
349+
350+
SILType parentTy = rootTy;
348351

349352
// First check if _storedInlineOffset would return an offset or nil. Basically
350353
// only stored struct and tuple elements produce an offset. Everything else
@@ -381,14 +384,15 @@ bool SILCombiner::tryOptimizeKeypathOffsetOf(ApplyInst *AI,
381384
hasOffset = false;
382385
break;
383386
}
384-
parentTy = component.getComponentType();
387+
parentTy = f->getLoweredType(Lowering::AbstractionPattern::getOpaque(),
388+
component.getComponentType());
385389
}
386390

387391
SILLocation loc = AI->getLoc();
388392
SILValue result;
389393

390394
if (hasOffset) {
391-
SILType rootAddrTy = SILType::getPrimitiveAddressType(rootTy);
395+
SILType rootAddrTy = rootTy.getAddressType();
392396
SILValue rootAddr = Builder.createBaseAddrForOffset(loc, rootAddrTy);
393397

394398
auto projector = KeyPathProjector::create(kp, rootAddr, loc, Builder);

test/SILOptimizer/keypath_offset.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ struct TupleProperties {
6161

6262
typealias Tuple<T, U> = (S<T>, C<U>)
6363

64+
typealias TupleOfFunctions = (a: @convention(c) () -> (), b: @convention(c) () -> ())
65+
6466
func getIdentityKeyPathOfType<T>(_: T.Type) -> KeyPath<T, T> {
6567
return \.self
6668
}
@@ -157,6 +159,15 @@ func testTupleOffsets() {
157159
printOffset(TLayout.offset(of: \Tuple<Int, Int>.1))
158160
}
159161

162+
// CHECK-LABEL: sil {{.*}} @$s4test0A16TupleOfFunctionsyyF
163+
// CHECK-NOT: _storedInlineOffset
164+
// CHECK-NOT: class_method
165+
// CHECK: } // end sil function '$s4test0A16TupleOfFunctionsyyF'
166+
@inline(never)
167+
func testTupleOfFunctions() {
168+
printOffset(MemoryLayout<TupleOfFunctions>.offset(of: \.b))
169+
}
170+
160171
// CHECK-LABEL: sil {{.*}} @$s4test0A19GenericTupleOffsetsyyxmlF
161172
// CHECK-NOT: _storedInlineOffset
162173
// CHECK-NOT: class_method
@@ -194,4 +205,6 @@ print("### testGenericTupleOffsets")
194205
testGenericTupleOffsets(Int.self)
195206
print("### testResilientOffsets")
196207
testResilientOffsets()
208+
print("### testTupleOfFunctions")
209+
testTupleOfFunctions()
197210

0 commit comments

Comments
 (0)