1// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -fobjc-arc -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 ptr, 38// CHECK: [[BIG:%.*]] = alloca %struct.Big, 39// CHECK: br label %for.cond 40// 41// CHECK: for.cond: 42// CHECK-NEXT: [[RECEIVER:%.*]] = load ptr, ptr [[P]], 43// CHECK-NEXT: [[ISNIL:%.*]] = icmp eq ptr [[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: call void @llvm.memset.p0.i64(ptr align 4 [[BIG]], i8 0, i64 48, i1 false) 53// CHECK-NEXT: br label %continue 54// 55// CHECK: continue: 56// CHECK-NEXT: br label %for.cond 57void test_loop_zeroing(id<P> p) { 58 for (;;) { 59 Big big = [p foo]; 60 } 61} 62 63// CHECK-LABEL: define{{.*}} void @test_zeroing_and_consume( 64// CHECK: [[P:%.*]] = alloca ptr, 65// CHECK: [[Q:%.*]] = alloca ptr, 66// CHECK: [[BIG:%.*]] = alloca %struct.Big, 67// CHECK: br label %for.cond 68// 69// CHECK: for.cond: 70// CHECK-NEXT: [[RECEIVER:%.*]] = load ptr, ptr [[P]], 71// CHECK-NEXT: [[Q_LOAD:%.*]] = load ptr, ptr [[Q]], 72// CHECK-NEXT: [[Q_RETAIN:%.*]] = call ptr @llvm.objc.retain(ptr [[Q_LOAD]]) 73// CHECK-NEXT: [[ISNIL:%.*]] = icmp eq ptr [[RECEIVER]], null 74// CHECK-NEXT: br i1 [[ISNIL]], label %nilReceiverCleanup, label %msgSend 75// 76// CHECK: msgSend: 77// CHECK: @objc_msg_lookup_sender 78// CHECK: call void {{%.*}}({{.*}} [[BIG]], 79// CHECK: br label %continue 80// 81// CHECK: nilReceiverCleanup: 82// CHECK-NEXT: call void @llvm.objc.release(ptr [[Q_RETAIN]]) 83// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[BIG]], i8 0, i64 48, i1 false) 84// CHECK-NEXT: br label %continue 85// 86// CHECK: continue: 87// CHECK-NEXT: br label %for.cond 88void test_zeroing_and_consume(id<P> p, id q) { 89 for (;;) { 90 Big big = [p fooConsuming: q]; 91 } 92} 93 94// CHECK-LABEL: define{{.*}} void @test_complex( 95// CHECK: [[P:%.*]] = alloca ptr, 96// CHECK: [[RECEIVER:%.*]] = load ptr, ptr [[P]], 97// CHECK-NEXT: [[ISNIL:%.*]] = icmp eq ptr [[RECEIVER]], null 98// CHECK-NEXT: br i1 [[ISNIL]], label %continue, label %msgSend 99// CHECK: msgSend: 100// CHECK: @objc_msg_lookup_sender 101// CHECK: br label %continue 102// CHECK: continue: 103// CHECK-NEXT: phi float 104// CHECK-NEXT: phi float 105void test_complex(id<P> p) { 106 _Complex float f = [p complex]; 107} 108