@@ -334,3 +334,72 @@ bb0(%0 : @guaranteed $Any, %1 : $*Any):
334334 %11 = tuple ()
335335 return %11 : $()
336336}
337+
338+ struct TwoFields {
339+ var a: Child
340+ var b: Child
341+ }
342+
343+ sil @no_read : $@convention(thin) (@in_guaranteed TwoFields) -> @out Child {
344+ [%0: write v**]
345+ [global: ]
346+ }
347+ sil @no_reads : $@convention(thin) (@in_guaranteed Child, @in_guaranteed TwoFields) -> () {
348+ [global: ]
349+ }
350+
351+ // CHECK-LABEL: sil [ossa] @argument_aliasing :
352+ // CHECK: %1 = alloc_stack
353+ // CHECK: apply %{{[0-9]+}}(%1, %0)
354+ // CHECK-LABEL: } // end sil function 'argument_aliasing'
355+ sil [ossa] @argument_aliasing : $@convention(thin) (@inout TwoFields) -> () {
356+ bb0(%0 : $*TwoFields):
357+ %1 = alloc_stack $Child
358+ %2 = function_ref @no_read : $@convention(thin) (@in_guaranteed TwoFields) -> @out Child
359+ %3 = apply %2(%1, %0) : $@convention(thin) (@in_guaranteed TwoFields) -> @out Child
360+ %4 = struct_element_addr %0, #TwoFields.a
361+ copy_addr [take] %1 to %4
362+ dealloc_stack %1
363+ %7 = tuple ()
364+ return %7
365+ }
366+
367+ // CHECK-LABEL: sil [ossa] @no_argument_aliasing :
368+ // CHECK-NOT: alloc_stack
369+ // CHECK: [[A:%.*]] = struct_element_addr %0 : $*TwoFields, #TwoFields.a
370+ // CHECK-NEXT: destroy_addr [[A]]
371+ // CHECK: apply %{{[0-9]+}}([[A]], %1)
372+ // CHECK-NOT: copy_addr
373+ // CHECK-LABEL: } // end sil function 'no_argument_aliasing'
374+ sil [ossa] @no_argument_aliasing : $@convention(thin) (@inout TwoFields, @inout TwoFields) -> () {
375+ bb0(%0 : $*TwoFields, %1 : $*TwoFields):
376+ %2 = alloc_stack $Child
377+ %3 = function_ref @no_read : $@convention(thin) (@in_guaranteed TwoFields) -> @out Child
378+ %4 = apply %3(%2, %1) : $@convention(thin) (@in_guaranteed TwoFields) -> @out Child
379+ %5 = struct_element_addr %0, #TwoFields.a
380+ copy_addr [take] %2 to %5
381+ dealloc_stack %2
382+ %8 = tuple ()
383+ return %8
384+ }
385+
386+ // CHECK-LABEL: sil [ossa] @guaranteed_argument_aliasing :
387+ // CHECK-NOT: alloc_stack
388+ // CHECK: [[A:%.*]] = struct_element_addr %0 : $*TwoFields, #TwoFields.a
389+ // CHECK-NEXT: destroy_addr [[A]]
390+ // CHECK: apply %{{[0-9]+}}([[A]], %0)
391+ // CHECK-NOT: copy_addr
392+ // CHECK-LABEL: } // end sil function 'guaranteed_argument_aliasing'
393+ sil [ossa] @guaranteed_argument_aliasing : $@convention(thin) (@inout TwoFields, @owned Child) -> () {
394+ bb0(%0 : $*TwoFields, %1 : @owned $Child):
395+ %2 = alloc_stack $Child
396+ store %1 to [init] %2
397+ %3 = function_ref @no_reads : $@convention(thin) (@in_guaranteed Child, @in_guaranteed TwoFields) -> ()
398+ %4 = apply %3(%2, %0) : $@convention(thin) (@in_guaranteed Child, @in_guaranteed TwoFields) -> ()
399+ %5 = struct_element_addr %0, #TwoFields.a
400+ copy_addr [take] %2 to %5
401+ dealloc_stack %2
402+ %8 = tuple ()
403+ return %8
404+ }
405+
0 commit comments