@@ -365,6 +365,44 @@ entry(%addr : $*X, %instance : @owned $X):
365
365
return %retval : $()
366
366
}
367
367
368
+ // Hoist up to a (transitive) use of an address_to_pointer instruction. In
369
+ // particular, do _some_ hoisting despite the fact that such an instruction is
370
+ // a use.
371
+ //
372
+ // CHECK-LABEL: sil [ossa] @hoist_upto_address_to_pointer_use : {{.*}} {
373
+ // CHECK: address_to_pointer
374
+ // CHECK: pointer_to_address
375
+ // CHECK: load [copy]
376
+ // CHECK: destroy_addr
377
+ // CHECK: tuple
378
+ // CHECK-LABEL: } // end sil function 'hoist_upto_address_to_pointer_use'
379
+ sil [ossa] @hoist_upto_address_to_pointer_use : $@convention(thin) (@in X) -> (@owned X) {
380
+ entry(%instance : $*X):
381
+ %pointer = address_to_pointer %instance : $*X to $Builtin.RawPointer
382
+ %addr = pointer_to_address %pointer : $Builtin.RawPointer to $*X
383
+ %value = load [copy] %addr : $*X
384
+ %retval = tuple ()
385
+ destroy_addr %instance : $*X
386
+ return %value : $X
387
+ }
388
+
389
+ // Hoist even if the pointerified address gets used.
390
+ //
391
+ // CHECK-LABEL: sil [ossa] @hoist_despite_use_of_pointer : {{.*}} {
392
+ // CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] :
393
+ // CHECK-NEXT: destroy_addr [[INSTANCE]]
394
+ // CHECK-LABEL: } // end sil function 'hoist_despite_use_of_pointer'
395
+ sil [ossa] @hoist_despite_use_of_pointer : $@convention(thin) (@inout X) -> () {
396
+ entry(%instance : $*X):
397
+ %addr_for_pointer = alloc_stack $Builtin.RawPointer
398
+ %pointer = address_to_pointer %instance : $*X to $Builtin.RawPointer
399
+ store %pointer to [trivial] %addr_for_pointer : $*Builtin.RawPointer
400
+ %retval = tuple ()
401
+ destroy_addr %instance : $*X
402
+ dealloc_stack %addr_for_pointer : $*Builtin.RawPointer
403
+ return %retval : $()
404
+ }
405
+
368
406
// Fold destroy_addr and a load [copy] into a load [take] even when that
369
407
// load [take] is guarded by an access scope.
370
408
//
0 commit comments