Skip to content

Commit f388361

Browse files
committed
SimplifyBuiltin: fix a wrong constant folding of the is_same_metatype builtin for function types
We need to compare the not lowered types, because function types may differ in their original version but are equal in the lowered version, e.g. ``` ((Int, Int) -> ()) (((Int, Int)) -> ()) ``` Fixes a miscompile
1 parent 04e0907 commit f388361

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,12 @@ private func typesOfValuesAreEqual(_ lhs: Value, _ rhs: Value, in function: Func
286286
rhsExistential.metatype is MetatypeInst
287287

288288
if typesAreExact {
289-
if lhsTy == rhsTy {
289+
// We need to compare the not lowered types, because function types may differ in their original version
290+
// but are equal in the lowered version, e.g.
291+
// ((Int, Int) -> ())
292+
// (((Int, Int)) -> ())
293+
//
294+
if lhsMetatype == rhsMetatype {
290295
return true
291296
}
292297
// Comparing types of different classes which are in a sub-class relation is not handled by the

test/SILOptimizer/simplify_builtin.sil

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,11 @@ bb0:
258258
return %4 : $Builtin.Int1
259259
}
260260

261-
// CHECK-LABEL: sil @different_function_metatype
261+
// CHECK-LABEL: sil @different_function_metatype1
262262
// CHECK: [[R:%.*]] = integer_literal $Builtin.Int1, 0
263263
// CHECK-NEXT: return [[R]]
264-
// CHECK: } // end sil function 'different_function_metatype'
265-
sil @different_function_metatype : $@convention(thin) () -> Builtin.Int1 {
264+
// CHECK: } // end sil function 'different_function_metatype1'
265+
sil @different_function_metatype1 : $@convention(thin) () -> Builtin.Int1 {
266266
bb0:
267267
%0 = metatype $@thick ((Int) -> Bool).Type
268268
%1 = metatype $@thick ((Float) -> Bool).Type
@@ -272,6 +272,20 @@ bb0:
272272
return %4 : $Builtin.Int1
273273
}
274274

275+
// CHECK-LABEL: sil @different_function_metatype2
276+
// CHECK: [[R:%.*]] = builtin "is_same_metatype"
277+
// CHECK: return [[R]]
278+
// CHECK: } // end sil function 'different_function_metatype2'
279+
sil @different_function_metatype2 : $@convention(thin) () -> Builtin.Int1 {
280+
bb0:
281+
%0 = metatype $@thick ((Int, Int) -> ()).Type
282+
%1 = metatype $@thick (((Int, Int)) -> ()).Type
283+
%2 = init_existential_metatype %0 : $@thick ((Int, Int) -> ()).Type, $@thick Any.Type
284+
%3 = init_existential_metatype %1 : $@thick (((Int, Int)) -> ()).Type, $@thick Any.Type
285+
%4 = builtin "is_same_metatype"(%2 : $@thick Any.Type, %3 : $@thick Any.Type) : $Builtin.Int1
286+
return %4 : $Builtin.Int1
287+
}
288+
275289
// CHECK-LABEL: sil @same_metatype_dynamic_self
276290
// CHECK: [[R:%.*]] = integer_literal $Builtin.Int1, -1
277291
// CHECK-NEXT: return [[R]]

0 commit comments

Comments
 (0)