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