@@ -349,3 +349,142 @@ bb2:
349349 unwind
350350}
351351
352+ struct Int {
353+ var _value: Builtin.Int64
354+ }
355+
356+ // Test to make sure AppliesToSpecialize in AllocBoxToStack is populated correctly when there are common function calls for mutiple allox_boxes.
357+ // Order of function calls constructed in PromotedOperands: bar common bas common.
358+ // AppliesToSpecialize should have the order: bar bas common.
359+ // Only then, the functions get specialized correctly, and we won't see an assert in checkNoPromotedBoxInApply.
360+ // CHECK-LABEL: sil [noinline] [ossa] @$testdfs1 :
361+ // CHECK-NOT : alloc_box ${ var Int64 }, var, name "x"
362+ // CHECK-NOT : alloc_box ${ var Int64 }, var, name "y"
363+ // CHECK-LABEL:} // end sil function '$testdfs1'
364+ sil [noinline] [ossa] @$testdfs1 : $@convention(thin) () -> Int64 {
365+ bb0:
366+ %0 = alloc_box ${ var Int64 }, var, name "x"
367+ %1 = project_box %0 : ${ var Int64 }, 0
368+ %2 = integer_literal $Builtin.Int64, 0
369+ %3 = struct $Int64 (%2 : $Builtin.Int64)
370+ store %3 to [trivial] %1 : $*Int64
371+ %5 = alloc_box ${ var Int64 }, var, name "y"
372+ %6 = project_box %5 : ${ var Int64 }, 0
373+ %7 = integer_literal $Builtin.Int64, 0
374+ %8 = struct $Int64 (%7 : $Builtin.Int64)
375+ store %8 to [trivial] %6 : $*Int64
376+ %10 = function_ref @$testdfs1common : $@convention(thin) (@guaranteed { var Int64 }, @guaranteed { var Int64 }) -> Int64
377+ %11 = apply %10(%0, %5) : $@convention(thin) (@guaranteed { var Int64 }, @guaranteed { var Int64 }) -> Int64
378+ destroy_value %5 : ${ var Int64 }
379+ destroy_value %0 : ${ var Int64 }
380+ return %11 : $Int64
381+ }
382+
383+ sil private [noinline] [ossa] @$testdfs1common : $@convention(thin) (@guaranteed { var Int64 }, @guaranteed { var Int64 }) -> Int64 {
384+ bb0(%0 : @guaranteed ${ var Int64 }, %1 : @guaranteed ${ var Int64 }):
385+ %proj1 = project_box %0 : ${ var Int64 }, 0
386+ %proj2 = project_box %1 : ${ var Int64 }, 0
387+ %barfunc = function_ref @$testdfs1bar : $@convention(thin) (@guaranteed { var Int64 }) -> Int64
388+ %res1 = apply %barfunc(%0) : $@convention(thin) (@guaranteed { var Int64 }) -> Int64
389+ %basfunc = function_ref @$testdfs1bas : $@convention(thin) (@guaranteed { var Int64 }) -> Int64
390+ %res2 = apply %basfunc(%1) : $@convention(thin) (@guaranteed { var Int64 }) -> Int64
391+ %func = function_ref @$blackhole : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
392+ %tmp1 = apply %func<Int64>(%proj1) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
393+ %tmp2 = apply %func<Int64>(%proj2) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
394+ %res = load [trivial] %proj1 : $*Int64
395+ return %res : $Int64
396+ }
397+
398+ sil private [noinline] [ossa] @$testdfs1bar : $@convention(thin) (@guaranteed { var Int64 }) -> Int64 {
399+ bb0(%0 : @guaranteed ${ var Int64 }):
400+ %1 = project_box %0 : ${ var Int64 }, 0
401+ %4 = load [trivial] %1 : $*Int64
402+ return %4 : $Int64
403+ }
404+
405+ sil private [noinline] [ossa] @$testdfs1bas : $@convention(thin) (@guaranteed { var Int64 }) -> Int64 {
406+ bb0(%0 : @guaranteed ${ var Int64 }):
407+ %1 = project_box %0 : ${ var Int64 }, 0
408+ %4 = load [trivial] %1 : $*Int64
409+ return %4 : $Int64
410+ }
411+
412+ // Test to make sure we don't optimize the case when we have an inner common function call for multiple boxes.
413+ // We don't optimize this case now, because we don't have additional logic to correctly construct AppliesToSpecialize
414+ // Order of function calls constructed in PromotedOperands: bar innercommon local1 bas innercommon local2
415+ // AppliesToSpecialize should have the order: bar bas innercommon local1 local2
416+ // Since we don't maintain any tree like data structure with more info on the call tree, this is not possible to contruct today
417+ // CHECK-LABEL: sil [noinline] [ossa] @$testdfs2 :
418+ // CHECK: alloc_box ${ var Int }, var, name "x"
419+ // CHECK: alloc_box ${ var Int }, var, name "y"
420+ // CHECK-LABEL:} // end sil function '$testdfs2'
421+ sil [noinline] [ossa] @$testdfs2 : $@convention(thin) () -> Int {
422+ bb0:
423+ %0 = alloc_box ${ var Int }, var, name "x"
424+ %1 = project_box %0 : ${ var Int }, 0
425+ %2 = integer_literal $Builtin.Int64, 0
426+ %3 = struct $Int (%2 : $Builtin.Int64)
427+ store %3 to [trivial] %1 : $*Int
428+ %5 = alloc_box ${ var Int }, var, name "y"
429+ %6 = project_box %5 : ${ var Int }, 0
430+ %7 = integer_literal $Builtin.Int64, 0
431+ %8 = struct $Int (%7 : $Builtin.Int64)
432+ store %8 to [trivial] %6 : $*Int
433+ %10 = function_ref @$testdfs2local1 : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int
434+ %11 = apply %10(%0, %5) : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int
435+ %12 = function_ref @$testdfs2local2 : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int
436+ %13 = apply %12(%0, %5) : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int
437+ %14 = struct_extract %11 : $Int, #Int._value
438+ %15 = struct_extract %13 : $Int, #Int._value
439+ %16 = integer_literal $Builtin.Int1, -1
440+ %17 = builtin "sadd_with_overflow_Int64"(%14 : $Builtin.Int64, %15 : $Builtin.Int64, %16 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
441+ (%18, %19) = destructure_tuple %17 : $(Builtin.Int64, Builtin.Int1)
442+ cond_fail %19 : $Builtin.Int1, "arithmetic overflow"
443+ %21 = struct $Int (%18 : $Builtin.Int64)
444+ destroy_value %5 : ${ var Int }
445+ destroy_value %0 : ${ var Int }
446+ return %21 : $Int
447+ }
448+
449+ sil private [noinline] [ossa] @$testdfs2bar : $@convention(thin) (@guaranteed { var Int }) -> Int {
450+ bb0(%0 : @guaranteed ${ var Int }):
451+ %1 = project_box %0 : ${ var Int }, 0
452+ %4 = load [trivial] %1 : $*Int
453+ return %4 : $Int
454+ }
455+
456+ sil private [noinline] [ossa] @$testdfs2bas : $@convention(thin) (@guaranteed { var Int }) -> Int {
457+ bb0(%0 : @guaranteed ${ var Int }):
458+ %1 = project_box %0 : ${ var Int }, 0
459+ %4 = load [trivial] %1 : $*Int
460+ return %4 : $Int
461+ }
462+
463+ sil private [noinline] [ossa] @$testdfs2innercommon : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int {
464+ bb0(%0 : @guaranteed ${ var Int }, %1 : @guaranteed ${ var Int }):
465+ %2 = project_box %0 : ${ var Int }, 0
466+ %4 = project_box %1 : ${ var Int }, 0
467+ %8 = function_ref @$testdfs2bar : $@convention(thin) (@guaranteed { var Int }) -> Int
468+ %9 = apply %8(%0) : $@convention(thin) (@guaranteed { var Int }) -> Int
469+ %11 = function_ref @$testdfs2bas : $@convention(thin) (@guaranteed { var Int }) -> Int
470+ %12 = apply %11(%1) : $@convention(thin) (@guaranteed { var Int }) -> Int
471+ return %12 : $Int
472+ }
473+
474+ sil private [noinline] [ossa] @$testdfs2local1 : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int {
475+ bb0(%0 : @guaranteed ${ var Int }, %1 : @guaranteed ${ var Int }):
476+ %2 = project_box %0 : ${ var Int }, 0
477+ %4 = project_box %1 : ${ var Int }, 0
478+ %7 = function_ref @$testdfs2innercommon : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int
479+ %8 = apply %7(%0, %1) : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int
480+ return %8 : $Int
481+ }
482+
483+ sil private [noinline] [ossa] @$testdfs2local2 : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int {
484+ bb0(%0 : @guaranteed ${ var Int }, %1 : @guaranteed ${ var Int }):
485+ %2 = project_box %0 : ${ var Int }, 0
486+ %4 = project_box %1 : ${ var Int }, 0
487+ %7 = function_ref @$testdfs2innercommon : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int
488+ %8 = apply %7(%0, %1) : $@convention(thin) (@guaranteed { var Int }, @guaranteed { var Int }) -> Int
489+ return %8 : $Int
490+ }
0 commit comments