Files
swift-mirror/test/DebugInfo/salvage_addr_projections.sil
Emil Pedersen 601addcdc8 [DebugInfo] Salvage index_addr and index_raw_pointer
These binary instructions can only be salvaged if their second operand
is an integer_literal. The salvageBinaryInst is more generic, allowing
literals on both operands.
2026-07-01 20:02:11 +01:00

160 lines
7.4 KiB
Plaintext

// RUN: %target-sil-opt -sil-print-types %s -sil-combine -sil-print-debuginfo | %FileCheck %s
// Test that struct_element_addr, tuple_element_addr, ref_element_addr, and
// vector_base_addr are salvaged into debug reconstruction blocks when they
// become dead (only debug uses remain).
sil_stage canonical
import Builtin
import Swift
struct MyStruct {
@_hasStorage var x: Int64 { get set }
@_hasStorage var y: Int64 { get set }
}
class MyClass {
@_hasStorage var field: Int64 { get set }
deinit
init()
}
sil_scope 1 { loc "test.swift":1:1 parent @test_salvage_struct_element_addr : $@convention(thin) (@in_guaranteed MyStruct) -> () }
sil_scope 2 { loc "test.swift":10:1 parent @test_salvage_tuple_element_addr : $@convention(thin) (@in_guaranteed (Int64, Int64)) -> () }
sil_scope 3 { loc "test.swift":20:1 parent @test_salvage_ref_element_addr : $@convention(thin) (@guaranteed MyClass) -> () }
sil_scope 4 { loc "test.swift":30:1 parent @test_salvage_vector_base_addr : $@convention(thin) (@in_guaranteed Builtin.FixedArray<4, Int64>) -> () }
sil_scope 5 { loc "test.swift":40:1 parent @test_salvage_ref_tail_addr : $@convention(thin) (@guaranteed MyClass) -> () }
sil_scope 6 { loc "test.swift":50:1 parent @test_salvage_index_addr : $@convention(thin) (@in_guaranteed Int64) -> () }
sil_scope 7 { loc "test.swift":60:1 parent @test_salvage_index_raw_pointer : $@convention(thin) (Builtin.RawPointer) -> () }
// CHECK-LABEL: sil @test_salvage_struct_element_addr
// CHECK: bb0([[ADDR:%[0-9]+]] : $*MyStruct):
// CHECK: debug_value [[ADDR]] : $*MyStruct, let, name "field_x", transform {
// CHECK: bb0([[SEA_ARG:%[0-9]+]] : $*MyStruct):
// CHECK: [[SEA:%[0-9]+]] = struct_element_addr [[SEA_ARG]] : $*MyStruct, #MyStruct.x
// CHECK: [[SEA_LD:%[0-9]+]] = load [[SEA]] : $*Int64
// CHECK: return [[SEA_LD]] : $Int64
// CHECK: }
// CHECK: return
// CHECK-LABEL: } // end sil function 'test_salvage_struct_element_addr'
sil @test_salvage_struct_element_addr : $@convention(thin) (@in_guaranteed MyStruct) -> () {
bb0(%0 : $*MyStruct):
%1 = struct_element_addr %0 : $*MyStruct, #MyStruct.x
debug_value %1 : $*Int64, let, name "field_x", expr op_deref, loc "test.swift":1:1, scope 1
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @test_salvage_tuple_element_addr
// CHECK: bb0([[ADDR:%[0-9]+]] : $*(Int64, Int64)):
// CHECK: debug_value [[ADDR]] : $*(Int64, Int64), let, name "elt0", transform {
// CHECK: bb0([[TEA_ARG:%[0-9]+]] : $*(Int64, Int64)):
// CHECK: [[TEA:%[0-9]+]] = tuple_element_addr [[TEA_ARG]] : $*(Int64, Int64), 0
// CHECK: [[TEA_LD:%[0-9]+]] = load [[TEA]] : $*Int64
// CHECK: return [[TEA_LD]] : $Int64
// CHECK: }
// CHECK: return
// CHECK-LABEL: } // end sil function 'test_salvage_tuple_element_addr'
sil @test_salvage_tuple_element_addr : $@convention(thin) (@in_guaranteed (Int64, Int64)) -> () {
bb0(%0 : $*(Int64, Int64)):
%1 = tuple_element_addr %0 : $*(Int64, Int64), 0
debug_value %1 : $*Int64, let, name "elt0", expr op_deref, loc "test.swift":10:1, scope 2
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @test_salvage_ref_element_addr
// CHECK: bb0([[REF:%[0-9]+]] : $MyClass):
// CHECK: debug_value [[REF]] : $MyClass, let, name "obj_field", transform {
// CHECK: bb0([[REA_ARG:%[0-9]+]] : $MyClass):
// CHECK: [[REA:%[0-9]+]] = ref_element_addr [[REA_ARG]] : $MyClass, #MyClass.field
// CHECK: [[REA_LD:%[0-9]+]] = load [[REA]] : $*Int64
// CHECK: return [[REA_LD]] : $Int64
// CHECK: }
// CHECK: return
// CHECK-LABEL: } // end sil function 'test_salvage_ref_element_addr'
sil @test_salvage_ref_element_addr : $@convention(thin) (@guaranteed MyClass) -> () {
bb0(%0 : $MyClass):
%1 = ref_element_addr %0 : $MyClass, #MyClass.field
debug_value %1 : $*Int64, let, name "obj_field", expr op_deref, loc "test.swift":20:1, scope 3
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @test_salvage_vector_base_addr
// CHECK: bb0([[ADDR:%[0-9]+]] : $*Builtin.FixedArray<4, Int64>):
// CHECK: debug_value [[ADDR]] : $*Builtin.FixedArray<4, Int64>, let, name "base", transform {
// CHECK: bb0([[VBA_ARG:%[0-9]+]] : $*Builtin.FixedArray<4, Int64>):
// CHECK: [[VBA:%[0-9]+]] = vector_base_addr [[VBA_ARG]] : $*Builtin.FixedArray<4, Int64>
// CHECK: [[VBA_LD:%[0-9]+]] = load [[VBA]] : $*Int64
// CHECK: return [[VBA_LD]] : $Int64
// CHECK: }
// CHECK: return
// CHECK-LABEL: } // end sil function 'test_salvage_vector_base_addr'
sil @test_salvage_vector_base_addr : $@convention(thin) (@in_guaranteed Builtin.FixedArray<4, Int64>) -> () {
bb0(%0 : $*Builtin.FixedArray<4, Int64>):
%1 = vector_base_addr %0 : $*Builtin.FixedArray<4, Int64>
debug_value %1 : $*Int64, let, name "base", expr op_deref, loc "test.swift":30:1, scope 4
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @test_salvage_ref_tail_addr
// CHECK: bb0(%0 : $MyClass):
// CHECK: debug_value %0 : $MyClass, let, name "tail_elt", transform {
// CHECK: bb0(%0 : $MyClass):
// CHECK: %1 = ref_tail_addr %0 : $MyClass, $Int64
// CHECK: %2 = load %1 : $*Int64
// CHECK: return %2 : $Int64
// CHECK: }
// CHECK: return
// CHECK-LABEL: } // end sil function 'test_salvage_ref_tail_addr'
sil @test_salvage_ref_tail_addr : $@convention(thin) (@guaranteed MyClass) -> () {
bb0(%0 : $MyClass):
%1 = ref_tail_addr %0 : $MyClass, $Int64
debug_value %1 : $*Int64, let, name "tail_elt", expr op_deref, loc "test.swift":40:1, scope 5
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @test_salvage_index_addr
// CHECK: bb0(%0 : $*Int64):
// CHECK: debug_value %0 : $*Int64, let, name "elt2", transform {
// CHECK: bb0(%0 : $*Int64):
// CHECK: %1 = integer_literal $Builtin.Word, 2
// CHECK: %2 = index_addr %0 : $*Int64, %1 : $Builtin.Word
// CHECK: %3 = load %2 : $*Int64
// CHECK: return %3 : $Int64
// CHECK: }
// CHECK: return
// CHECK-LABEL: } // end sil function 'test_salvage_index_addr'
sil @test_salvage_index_addr : $@convention(thin) (@in_guaranteed Int64) -> () {
bb0(%0 : $*Int64):
%idx = integer_literal $Builtin.Word, 2
%1 = index_addr %0 : $*Int64, %idx : $Builtin.Word
debug_value %1 : $*Int64, let, name "elt2", expr op_deref, loc "test.swift":50:1, scope 6
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @test_salvage_index_raw_pointer
// CHECK: bb0(%0 : $Builtin.RawPointer):
// CHECK: debug_value %0 : $Builtin.RawPointer, let, name "offset_ptr", transform {
// CHECK: bb0(%0 : $Builtin.RawPointer):
// CHECK: %1 = integer_literal $Builtin.Word, 8
// CHECK: %2 = index_raw_pointer %0 : $Builtin.RawPointer, %1 : $Builtin.Word
// CHECK: return %2 : $Builtin.RawPointer
// CHECK: }
// CHECK: return
// CHECK-LABEL: } // end sil function 'test_salvage_index_raw_pointer'
sil @test_salvage_index_raw_pointer : $@convention(thin) (Builtin.RawPointer) -> () {
bb0(%0 : $Builtin.RawPointer):
%idx = integer_literal $Builtin.Word, 8
%1 = index_raw_pointer %0 : $Builtin.RawPointer, %idx : $Builtin.Word
debug_value %1 : $Builtin.RawPointer, let, name "offset_ptr", loc "test.swift":60:1, scope 7
%r = tuple ()
return %r : $()
}