1// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-freebsd -fobjc-arc -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s 2 3typedef struct { 4 int x[12]; 5} Big; 6 7@protocol P 8- (Big) foo; 9- (Big) fooConsuming: (__attribute__((ns_consumed)) id) arg; 10- (_Complex float) complex; 11@end 12 13@interface SuperClass 14- (Big) foo; 15@end 16 17@implementation TestClass : SuperClass 18// Check that we don't do a nil check when messaging self in ARC 19// (which forbids reassigning self) 20// CHECK-LABEL: define{{.*}} void @_i_TestClass__test_self_send( 21// CHECK-NOT: icmp 22// CHECK: @objc_msg_lookup_sender 23- (void) test_self_send { 24 Big big = [self foo]; 25} 26 27// Check that we don't do a nil test when messaging super. 28// CHECK-LABEL: define{{.*}} void @_i_TestClass__test_super_send( 29// CHECK-NOT: icmp 30// CHECK: @objc_msg_lookup_super 31- (void) test_super_send { 32 Big big = [super foo]; 33} 34@end 35 36// CHECK-LABEL: define{{.*}} void @test_loop_zeroing( 37// CHECK: [[P:%.*]] = alloca i8*, 38// CHECK: [[BIG:%.*]] = alloca %struct.Big, 39// CHECK: br label %for.cond 40// 41// CHECK: for.cond: 42// CHECK-NEXT: [[RECEIVER:%.*]] = load i8*, i8** [[P]], 43// CHECK-NEXT: [[ISNIL:%.*]] = icmp eq i8* [[RECEIVER]], null 44// CHECK-NEXT: br i1 [[ISNIL]], label %nilReceiverCleanup, label %msgSend 45// 46// CHECK: msgSend: 47// CHECK: @objc_msg_lookup_sender 48// CHECK: call void {{%.*}}({{.*}} [[BIG]], 49// CHECK: br label %continue 50// 51// CHECK: nilReceiverCleanup: 52// CHECK-NEXT: [[T0:%.*]] = bitcast %struct.Big* [[BIG]] to i8* 53// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[T0]], i8 0, i64 48, i1 false) 54// CHECK-NEXT: br label %continue 55// 56// CHECK: continue: 57// CHECK-NEXT: br label %for.cond 58void test_loop_zeroing(id<P> p) { 59 for (;;) { 60 Big big = [p foo]; 61 } 62} 63 64// CHECK-LABEL: define{{.*}} void @test_zeroing_and_consume( 65// CHECK: [[P:%.*]] = alloca i8*, 66// CHECK: [[Q:%.*]] = alloca i8*, 67// CHECK: [[BIG:%.*]] = alloca %struct.Big, 68// CHECK: br label %for.cond 69// 70// CHECK: for.cond: 71// CHECK-NEXT: [[RECEIVER:%.*]] = load i8*, i8** [[P]], 72// CHECK-NEXT: [[Q_LOAD:%.*]] = load i8*, i8** [[Q]], 73// CHECK-NEXT: [[Q_RETAIN:%.*]] = call i8* @llvm.objc.retain(i8* [[Q_LOAD]]) 74// CHECK-NEXT: [[ISNIL:%.*]] = icmp eq i8* [[RECEIVER]], null 75// CHECK-NEXT: br i1 [[ISNIL]], label %nilReceiverCleanup, label %msgSend 76// 77// CHECK: msgSend: 78// CHECK: @objc_msg_lookup_sender 79// CHECK: call void {{%.*}}({{.*}} [[BIG]], 80// CHECK: br label %continue 81// 82// CHECK: nilReceiverCleanup: 83// CHECK-NEXT: call void @llvm.objc.release(i8* [[Q_RETAIN]]) 84// CHECK-NEXT: [[T0:%.*]] = bitcast %struct.Big* [[BIG]] to i8* 85// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[T0]], i8 0, i64 48, i1 false) 86// CHECK-NEXT: br label %continue 87// 88// CHECK: continue: 89// CHECK-NEXT: br label %for.cond 90void test_zeroing_and_consume(id<P> p, id q) { 91 for (;;) { 92 Big big = [p fooConsuming: q]; 93 } 94} 95 96// CHECK-LABEL: define{{.*}} void @test_complex( 97// CHECK: [[P:%.*]] = alloca i8*, 98// CHECK: [[RECEIVER:%.*]] = load i8*, i8** [[P]], 99// CHECK-NEXT: [[ISNIL:%.*]] = icmp eq i8* [[RECEIVER]], null 100// CHECK-NEXT: br i1 [[ISNIL]], label %continue, label %msgSend 101// CHECK: msgSend: 102// CHECK: @objc_msg_lookup_sender 103// CHECK: br label %continue 104// CHECK: continue: 105// CHECK-NEXT: phi float 106// CHECK-NEXT: phi float 107void test_complex(id<P> p) { 108 _Complex float f = [p complex]; 109} 110