Skip to content

Commit 9a015f3

Browse files
committed
Add test cases for IRGen poison emission.
1 parent 97ec127 commit 9a015f3

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed

test/IRGen/debug_poison.swift

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

0 commit comments

Comments
 (0)