Under ARC, when we're passing the address of a strong variable
to an out-parameter using the indirect-writeback conversion,
and we copied the current value of the variable to the temporary,
make sure that we register an intrinsic use of that value with
the optimizer so that the value won't get released until we have
a chance to retain it.
rdar://13195034
llvm-svn: 177813
diff --git a/clang/test/CodeGenObjC/arc-blocks.m b/clang/test/CodeGenObjC/arc-blocks.m
index 503c7d2..c7bc502 100644
--- a/clang/test/CodeGenObjC/arc-blocks.m
+++ b/clang/test/CodeGenObjC/arc-blocks.m
@@ -80,13 +80,14 @@
// CHECK-NEXT: bitcast
// CHECK-NEXT: getelementptr
// CHECK-NEXT: [[BLOCK:%.*]] = bitcast
- // CHECK-NEXT: [[T0:%.*]] = load i8** [[STRONG]]
- // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]]
+ // CHECK-NEXT: [[V:%.*]] = load i8** [[STRONG]]
+ // CHECK-NEXT: store i8* [[V]], i8** [[TEMP]]
// CHECK-NEXT: [[F0:%.*]] = load i8**
// CHECK-NEXT: [[F1:%.*]] = bitcast i8* [[F0]] to void (i8*, i8**)*
// CHECK-NEXT: call void [[F1]](i8* [[BLOCK]], i8** [[TEMP]])
// CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]]
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V]]) [[NUW]]
// CHECK-NEXT: [[T2:%.*]] = load i8** [[STRONG]]
// CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]]
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
diff --git a/clang/test/CodeGenObjC/arc-ternary-op.m b/clang/test/CodeGenObjC/arc-ternary-op.m
index ed14e9d..f70e886 100644
--- a/clang/test/CodeGenObjC/arc-ternary-op.m
+++ b/clang/test/CodeGenObjC/arc-ternary-op.m
@@ -61,11 +61,13 @@
// CHECK: [[T0:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]]
// CHECK-NEXT: br label
- // CHECK: call void @test1_sink(i8** [[T1]])
+ // CHECK: [[W:%.*]] = phi i8* [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ]
+ // CHECK-NEXT: call void @test1_sink(i8** [[T1]])
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
// CHECK-NEXT: br i1 [[T0]],
// CHECK: [[T0:%.*]] = load i8** [[TEMP1]]
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W]]) [[NUW]]
// CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T1]], i8** [[ARG]]
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
diff --git a/clang/test/CodeGenObjC/arc.m b/clang/test/CodeGenObjC/arc.m
index 3778625..45cb5d7 100644
--- a/clang/test/CodeGenObjC/arc.m
+++ b/clang/test/CodeGenObjC/arc.m
@@ -865,8 +865,8 @@
// CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[A]]
// CHECK-NEXT: load [[TEST33]]** [[PTR]]
- // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]]
- // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP0]]
+ // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]** [[A]]
+ // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP0]]
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: bitcast
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP0]])
@@ -874,14 +874,15 @@
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]*
+ // CHECK-NEXT: call void (...)* @clang.arc.use([[A_T]]* [[W0]]) [[NUW]]
// CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]]
// CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]]
// CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T5]])
// CHECK-NEXT: load [[TEST33]]** [[PTR]]
- // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]]
- // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP1]]
+ // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]** [[A]]
+ // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP1]]
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: bitcast
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP1]])
@@ -889,6 +890,7 @@
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]*
+ // CHECK-NEXT: call void (...)* @clang.arc.use([[A_T]]* [[W0]]) [[NUW]]
// CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]]
// CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]]
// CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8*
@@ -962,15 +964,16 @@
// CHECK-NEXT: [[TEMP:%.*]] = alloca i8*
// CHECK-NEXT: store [[TEST37]]* null, [[TEST37]]** [[VAR]]
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]** [[VAR]]
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8*
- // CHECK-NEXT: store i8* [[T1]], i8** [[TEMP]]
+ // CHECK-NEXT: [[W0:%.*]] = load [[TEST37]]** [[VAR]]
+ // CHECK-NEXT: [[W1:%.*]] = bitcast [[TEST37]]* [[W0]] to i8*
+ // CHECK-NEXT: store i8* [[W1]], i8** [[TEMP]]
// CHECK-NEXT: call void @test37_helper(i8** [[TEMP]])
// CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]]
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST37]]*
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST37]]* [[T1]] to i8*
// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]])
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST37]]*
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W1]]) [[NUW]]
// CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]** [[VAR]]
// CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]]
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8*
diff --git a/clang/test/CodeGenObjCXX/arc.mm b/clang/test/CodeGenObjCXX/arc.mm
index aa40f93..1888dbe 100644
--- a/clang/test/CodeGenObjCXX/arc.mm
+++ b/clang/test/CodeGenObjCXX/arc.mm
@@ -76,11 +76,13 @@
// CHECK: [[T0:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]]
// CHECK-NEXT: br label
+ // CHECK: [[W0:%.*]] = phi i8* [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ]
// CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(i8** [[T1]])
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
// CHECK-NEXT: br i1 [[T0]],
// CHECK: [[T0:%.*]] = load i8** [[TEMP1]]
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W0]])
// CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T1]], i8** [[ARG]]
// CHECK-NEXT: call void @objc_release(i8* [[T2]])