1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
// RUN: %target-swift-frontend -primary-file %s -emit-ir -Onone -enable-copy-propagation | %FileCheck %s -DINT=i%target-ptrsize
//
// This test is currently disabled because mandatory copy propagation
// is not part of the pipeline. It may be re-added to the pipeline,
// but it isn't clear if we'll still need to emit poison references by
// that time.
//
// REQUIRES: mandatory_copy_propagation
// Test debug_value [poison] emission
class K {
init() {}
}
protocol P : AnyObject {}
class D : P {}
protocol Q {}
class E : Q {}
func useInt(_ i: Int) {}
func useAny(_: Any) {}
func useOptionalAny(_: Any?) {}
func useNone() {}
func getK() -> K { return K() }
func getOptionalK() -> K? { return K() }
private func useK(_: K) -> Int {
return 2
}
private func useOptionalK(_: K?) -> Int {
return 2
}
// Hoist and poison 'b' above useInt(y).
//
// CHECK-LABEL: define {{.*}}swiftcc void @"$s12debug_poison13testPoisonRefyyF"
// CHECK: %b.debug = alloca %T12debug_poison1KC*
// CHECK: %y.debug = alloca [[INT]]
// CHECK: [[REF:%.*]] = call {{.*}} %T12debug_poison1KC* @"$s12debug_poison4getKAA1KCyF"()
// CHECK: store %T12debug_poison1KC* [[REF]], %T12debug_poison1KC** %b.debug
// CHECK: [[Y:%.*]] = call {{.*}} [[INT]] @"$s12debug_poison4use{{.*}}"(%T12debug_poison1KC* [[REF]])
// CHECK: call void {{.*}} @swift_release {{.*}} [[REF]]
// CHECK: store %T12debug_poison1KC* inttoptr ([[INT]] 1088 to %T12debug_poison1KC*), %T12debug_poison1KC** %b.debug
// CHECK: store [[INT]] [[Y]], [[INT]]* %y.debug
// CHECK: call {{.*}} void @"$s12debug_poison6useIntyySiF"([[INT]] [[Y]])
public func testPoisonRef() {
let b = getK()
let y = useK(b)
useInt(y)
}
// Hoist and poison 'b' above useInt(y).
//
// CHECK-LABEL: define {{.*}}swiftcc void @"$s12debug_poison21testPoisonOptionalRefyyF"
// CHECK: %b.debug = alloca [[INT]]
// CHECK: %y.debug = alloca [[INT]]
// CHECK: [[REF:%.*]] = call {{.*}} [[INT]] @"$s12debug_poison12getOptionalKAA1KCSgyF"()
// CHECK: store [[INT]] [[REF]], [[INT]]* %b.debug
// CHECK: [[Y:%.*]] = call {{.*}} [[INT]] @"$s12debug_poison12useOptionalK{{.*}}"([[INT]] [[REF]])
// CHECK: call void @swift_release
// CHECK: [[NIL:%.*]] = icmp eq [[INT]] [[REF]], 0
// CHECK: [[POISON:%.*]] = select i1 [[NIL]], [[INT]] [[REF]], [[INT]] 1088
// CHECK: store [[INT]] [[POISON]], [[INT]]* %b.debug
// CHECK: store [[INT]] [[Y]], [[INT]]* %y.debug
// CHECK: call {{.*}} void @"$s12debug_poison6useIntyySiF"([[INT]] [[Y]])
public func testPoisonOptionalRef() {
let b: K? = getOptionalK()
let y = useOptionalK(b)
useInt(y)
}
// Hoist and poison 'b' above useNone.
//
// CHECK-LABEL: define {{.*}}swiftcc void @"$s12debug_poison21testPoisonExistentialyyF"
// CHECK: %b.debug = alloca %T12debug_poison1PP
// CHECK: [[INIT:%.*]] = call {{.*}} %T12debug_poison1DC* @"$s12debug_poison1DCACycfC"(
// CHECK: [[REF:%.*]] = bitcast %T12debug_poison1DC* [[INIT]] to %[[REFTY:.*]]*
// CHECK: [[GEP0:%.*]] = getelementptr inbounds %T12debug_poison1PP, %T12debug_poison1PP* %b.debug, i32 0, i32 0
// CHECK: store %[[REFTY]]* [[REF]], %[[REFTY]]** [[GEP0]]
// CHECK: store i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$s12debug_poison1DCAA1PAAWP", i32 0, i32 0), i8***
// CHECK: call %[[REFTY]]* @swift_{{unknownObjectRetain|retain}}(%[[REFTY]]* returned [[REF]])
// CHECK: store %[[REFTY]]* [[REF]], %[[REFTY]]**
// CHECK: call {{.*}} void @"$s12debug_poison6useAnyyyypF"(
// CHECK: call void @swift_{{unknownObjectRelease|release}}(%[[REFTY]]* [[REF]])
// CHECK: [[GEP1:%.*]] = getelementptr inbounds %T12debug_poison1PP, %T12debug_poison1PP* %b.debug, i32 0, i32 0
// CHECK: store %[[REFTY]]* inttoptr ([[INT]] 1088 to %[[REFTY]]*), %[[REFTY]]** [[GEP1]]
// CHECK: call {{.*}} void @"$s12debug_poison7useNoneyyF"()
public func testPoisonExistential() {
let b: P = D()
useAny(b)
useNone()
}
// Hoist and poison 'b' above useNone.
//
// CHECK-LABEL: define {{.*}}swiftcc void @"$s12debug_poison19testPoisonCompositeyyF"()
// CHECK: %b.debug = alloca %T12debug_poison1Q_Xl
// CHECK: [[INIT:%.*]] = call {{.*}} %T12debug_poison1EC* @"$s12debug_poison1ECACycfC"(
// CHECK: [[REF:%.*]] = bitcast %T12debug_poison1EC* [[INIT]] to %[[REFTY]]*
// CHECK: [[GEP0:%.*]] = getelementptr inbounds %T12debug_poison1Q_Xl, %T12debug_poison1Q_Xl* %b.debug, i32 0, i32 0
// CHECK: store %[[REFTY]]* [[REF]], %[[REFTY]]** [[GEP0]]
// CHECK: store i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$s12debug_poison1ECAA1QAAWP", i32 0, i32 0), i8***
// CHECK: call %[[REFTY]]* @swift_{{unknownObjectRetain|retain}}(%[[REFTY]]* returned [[REF]])
// CHECK: store %[[REFTY]]* [[REF]], %[[REFTY]]**
// CHECK: call {{.*}} void @"$s12debug_poison6useAnyyyypF"(
// CHECK: call void @swift_{{unknownObjectRelease|release}}(%[[REFTY]]* [[REF]])
// CHECK: [[GEP1:%.*]] = getelementptr inbounds %T12debug_poison1Q_Xl, %T12debug_poison1Q_Xl* %b.debug, i32 0, i32 0
// CHECK: store %[[REFTY]]* inttoptr ([[INT]] 1088 to %[[REFTY]]*), %[[REFTY]]** [[GEP1]]
// CHECK: call {{.*}} void @"$s12debug_poison7useNoneyyF"()
public func testPoisonComposite() {
let b: Q & AnyObject = E()
useAny(b)
useNone()
}
// CopyPropagation hoists 'b' above useNone, but IRGen currently bails on emitting poison.
//
// CHECK-LABEL: define {{.*}}swiftcc void @"$s12debug_poison27testPoisonOptionalCompositeyyF"()
// CHECK: %b.debug = alloca %T12debug_poison1Q_XlSg
// CHECK: [[INIT:%.*]] = call {{.*}} %T12debug_poison1EC* @"$s12debug_poison1ECACycfC"(
// CHECK: [[REF0:%.*]] = bitcast %T12debug_poison1EC* [[INIT]] to %[[REFTY]]*
// CHECK: [[REFINT0:%.*]] = ptrtoint %[[REFTY]]* [[REF0]] to [[INT]]
// CHECK: [[SHADOW0:%.*]] = bitcast %T12debug_poison1Q_XlSg* %b.debug to { [[INT]], [[INT]] }*
// CHECK: [[GEP0:%.*]] = getelementptr inbounds {{.*}} [[SHADOW0]], i32 0, i32 0
// CHECK: store [[INT]] [[REFINT0]], [[INT]]* [[GEP0]]
// CHECK: store [[INT]] ptrtoint ([1 x i8*]* @"$s12debug_poison1ECAA1QAAWP" to [[INT]]),
// CHECK: [[REF1:%.*]] = inttoptr [[INT]] [[REFINT0]] to %[[REFTY]]*
// CHECK: call %[[REFTY]]* @swift_{{unknownObjectRetain|retain}}(%[[REFTY]]* returned [[REF1]])
// CHECK: icmp eq [[INT]] [[REFINT0]], 0
// CHECK: [[PHI:%.*]] = phi %[[REFTY]]*
// CHECK: call void @swift_{{unknownObjectRelease|release}}(%[[REFTY]]*
// CHECK: store %[[REFTY]]* [[PHI]], %[[REFTY]]**
// CHECK: call {{.*}} void @"$s12debug_poison14useOptionalAnyyyypSgF"(
//
// Currently no poison store here.
// CHECK-NOT: store
// CHECK: call {{.*}} void @"$s12debug_poison7useNoneyyF"()
public func testPoisonOptionalComposite() {
let b: Optional<Q & AnyObject> = E()
useOptionalAny(b)
useNone()
}
|