xref: /aosp_15_r20/external/clang/test/CodeGenObjC/arc-unopt.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -o - %s | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Li// A test to ensure that we generate fused calls at -O0.
4*67e74705SXin Li
5*67e74705SXin Li@class Test0;
6*67e74705SXin LiTest0 *test0(void) {
7*67e74705SXin Li  extern Test0 *test0_helper;
8*67e74705SXin Li  return test0_helper;
9*67e74705SXin Li
10*67e74705SXin Li  // CHECK:      [[LD:%.*]] = load [[TEST0:%.*]]*, [[TEST0:%.*]]** @test0_helper
11*67e74705SXin Li  // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]* [[LD]] to i8*
12*67e74705SXin Li  // CHECK-NEXT: [[T1:%.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* [[T0]])
13*67e74705SXin Li  // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST0]]*
14*67e74705SXin Li  // CHECK-NEXT: ret [[TEST0]]* [[T2]]
15*67e74705SXin Li}
16*67e74705SXin Li
17*67e74705SXin Liid test1(void) {
18*67e74705SXin Li  extern id test1_helper;
19*67e74705SXin Li  return test1_helper;
20*67e74705SXin Li
21*67e74705SXin Li  // CHECK:      [[LD:%.*]] = load i8*, i8** @test1_helper
22*67e74705SXin Li  // CHECK-NEXT: [[T0:%.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* [[LD]])
23*67e74705SXin Li  // CHECK-NEXT: ret i8* [[T0]]
24*67e74705SXin Li}
25*67e74705SXin Li
26*67e74705SXin Livoid test2(void) {
27*67e74705SXin Li  // CHECK:      [[X:%.*]] = alloca i8*
28*67e74705SXin Li  // CHECK-NEXT: store i8* null, i8** [[X]]
29*67e74705SXin Li  // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]])
30*67e74705SXin Li  // CHECK-NEXT: ret void
31*67e74705SXin Li  __weak id x;
32*67e74705SXin Li}
33*67e74705SXin Li
34*67e74705SXin Liid test3(void) {
35*67e74705SXin Li  extern id test3_helper(void);
36*67e74705SXin Li  // CHECK:      [[T0:%.*]] = call i8* @test3_helper()
37*67e74705SXin Li  // CHECK-NEXT: ret i8* [[T0]]
38*67e74705SXin Li  return test3_helper();
39*67e74705SXin Li}
40*67e74705SXin Li
41*67e74705SXin Li@interface Test4 { id x; } @end
42*67e74705SXin Li@interface Test4_sub : Test4 { id y; } @end
43*67e74705SXin LiTest4 *test4(void) {
44*67e74705SXin Li  extern Test4_sub *test4_helper(void);
45*67e74705SXin Li  // CHECK:      [[T0:%.*]] = call [[TEST4S:%.*]]* @test4_helper()
46*67e74705SXin Li  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST4S]]* [[T0]] to [[TEST4:%.*]]*
47*67e74705SXin Li  // CHECK-NEXT: ret [[TEST4]]* [[T1]]
48*67e74705SXin Li  return test4_helper();
49*67e74705SXin Li}
50*67e74705SXin Li
51*67e74705SXin Li// rdar://problem/9418404
52*67e74705SXin Li@class Test5;
53*67e74705SXin Livoid test5(void) {
54*67e74705SXin Li  Test5 *x, *y;
55*67e74705SXin Li  if ((x = y))
56*67e74705SXin Li    y = 0;
57*67e74705SXin Li
58*67e74705SXin Li// CHECK-LABEL:    define void @test5()
59*67e74705SXin Li// CHECK:      [[X:%.*]] = alloca [[TEST5:%.*]]*,
60*67e74705SXin Li// CHECK-NEXT: [[Y:%.*]] = alloca [[TEST5:%.*]]*,
61*67e74705SXin Li// CHECK-NEXT: store [[TEST5]]* null, [[TEST5]]** [[X]],
62*67e74705SXin Li// CHECK-NEXT: store [[TEST5]]* null, [[TEST5]]** [[Y]],
63*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = load [[TEST5]]*, [[TEST5]]** [[Y]],
64*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST5]]** [[X]] to i8**
65*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST5]]* [[T0]] to i8*
66*67e74705SXin Li// CHECK-NEXT: call void @objc_storeStrong(i8** [[T1]], i8* [[T2]])
67*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = icmp ne [[TEST5]]* [[T0]], null
68*67e74705SXin Li// CHECK-NEXT: br i1 [[T3]],
69*67e74705SXin Li}
70