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