mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Adding `move_value [lexical]` and `begin_borrow [lexical]` should happen all the time at this point. Remove the ability to omit these instructions and update the corresponding tests.
147 lines
6.4 KiB
Swift
147 lines
6.4 KiB
Swift
// 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()
|
|
}
|