Skip to content

Commit 40f05fa

Browse files
authored
Merge pull request swiftlang#63690 from eeckstein/fix-same-metatype-simplification
Swift Optimizer: fix a crash when simplifying same-metatype comparisons of function types
2 parents f68647a + 40ed0fb commit 40f05fa

File tree

5 files changed

+40
-9
lines changed

5 files changed

+40
-9
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ private extension BuiltinInst {
5656
let lhs = operands[0].value
5757
let rhs = operands[1].value
5858

59-
guard let equal = typesOfValuesAreEqual(lhs, rhs) else {
59+
guard let equal = typesOfValuesAreEqual(lhs, rhs, in: parentFunction) else {
6060
return
6161
}
6262
let builder = Builder(before: self, context)
@@ -66,7 +66,7 @@ private extension BuiltinInst {
6666
}
6767
}
6868

69-
private func typesOfValuesAreEqual(_ lhs: Value, _ rhs: Value) -> Bool? {
69+
private func typesOfValuesAreEqual(_ lhs: Value, _ rhs: Value, in function: Function) -> Bool? {
7070
if lhs == rhs {
7171
return true
7272
}
@@ -76,8 +76,8 @@ private func typesOfValuesAreEqual(_ lhs: Value, _ rhs: Value) -> Bool? {
7676
return nil
7777
}
7878

79-
let lhsTy = lhsExistential.operand.type.instanceTypeOfMetatype
80-
let rhsTy = rhsExistential.operand.type.instanceTypeOfMetatype
79+
let lhsTy = lhsExistential.operand.type.instanceTypeOfMetatype(in: function)
80+
let rhsTy = rhsExistential.operand.type.instanceTypeOfMetatype(in: function)
8181

8282
// Do we know the exact types? This is not the case e.g. if a type is passed as metatype
8383
// to the function.

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ public struct Type : CustomStringConvertible, NoReflectionChildren {
5353
NominalFieldsArray(type: self, function: function)
5454
}
5555

56-
public var instanceTypeOfMetatype: Type { SILType_instanceTypeOfMetatype(bridged).type }
56+
public func instanceTypeOfMetatype(in function: Function) -> Type {
57+
SILType_instanceTypeOfMetatype(bridged, function.bridged).type
58+
}
5759

5860
public var isCalleeConsumedFunction: Bool { SILType_isCalleeConsumedFunction(bridged) }
5961

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ SwiftInt SILType_isTuple(BridgedType type);
328328
SwiftInt SILType_isEnum(BridgedType type);
329329
bool SILType_isFunction(BridgedType type);
330330
bool SILType_isMetatype(BridgedType type);
331-
BridgedType SILType_instanceTypeOfMetatype(BridgedType type);
331+
BridgedType SILType_instanceTypeOfMetatype(BridgedType type, BridgedFunction function);
332332
BridgedDecl SILType_getNominal(BridgedType type);
333333
bool SILType_isOrContainsObjectiveCClass(BridgedType type);
334334
bool SILType_isCalleeConsumedFunction(BridgedType type);

lib/SIL/Utils/SILBridging.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,10 +545,12 @@ bool SILType_isMetatype(BridgedType type) {
545545
return castToSILType(type).is<MetatypeType>();
546546
}
547547

548-
BridgedType SILType_instanceTypeOfMetatype(BridgedType type) {
548+
BridgedType SILType_instanceTypeOfMetatype(BridgedType type, BridgedFunction function) {
549549
auto metaType = castToSILType(type).castTo<MetatypeType>();
550-
SILType instanceTy = SILType::getPrimitiveObjectType(metaType.getInstanceType());
551-
return {instanceTy.getOpaqueValue()};
550+
CanType instanceTy = metaType.getInstanceType();
551+
SILFunction *f = castToFunction(function);
552+
auto &tl = f->getModule().Types.getTypeLowering(instanceTy, TypeExpansionContext(*f));
553+
return {tl.getLoweredType().getOpaqueValue()};
552554
}
553555

554556
BridgedDecl SILType_getNominal(BridgedType type) {

test/SILOptimizer/simplify_builtin.sil

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,30 @@ bb0:
220220
return %4 : $Builtin.Int1
221221
}
222222

223+
// CHECK-LABEL: sil @same_function_metatype
224+
// CHECK: [[R:%.*]] = integer_literal $Builtin.Int1, -1
225+
// CHECK-NEXT: return [[R]]
226+
// CHECK: } // end sil function 'same_function_metatype'
227+
sil @same_function_metatype : $@convention(thin) () -> Builtin.Int1 {
228+
bb0:
229+
%0 = metatype $@thick ((Int) -> Bool).Type
230+
%1 = metatype $@thick ((Int) -> Bool).Type
231+
%2 = init_existential_metatype %0 : $@thick ((Int) -> Bool).Type, $@thick Any.Type
232+
%3 = init_existential_metatype %1 : $@thick ((Int) -> Bool).Type, $@thick Any.Type
233+
%4 = builtin "is_same_metatype"(%2 : $@thick Any.Type, %3 : $@thick Any.Type) : $Builtin.Int1
234+
return %4 : $Builtin.Int1
235+
}
236+
237+
// CHECK-LABEL: sil @different_function_metatype
238+
// CHECK: [[R:%.*]] = integer_literal $Builtin.Int1, 0
239+
// CHECK-NEXT: return [[R]]
240+
// CHECK: } // end sil function 'different_function_metatype'
241+
sil @different_function_metatype : $@convention(thin) () -> Builtin.Int1 {
242+
bb0:
243+
%0 = metatype $@thick ((Int) -> Bool).Type
244+
%1 = metatype $@thick ((Float) -> Bool).Type
245+
%2 = init_existential_metatype %0 : $@thick ((Int) -> Bool).Type, $@thick Any.Type
246+
%3 = init_existential_metatype %1 : $@thick ((Float) -> Bool).Type, $@thick Any.Type
247+
%4 = builtin "is_same_metatype"(%2 : $@thick Any.Type, %3 : $@thick Any.Type) : $Builtin.Int1
248+
return %4 : $Builtin.Int1
249+
}

0 commit comments

Comments
 (0)