1 ; RUN: llc < %s -mtriple=armv7-apple-ios6.0 | FileCheck %s 2 3 ; rdar://9877866 4 %struct.SmallStruct = type { i32, [8 x i32], [37 x i8] } 5 %struct.LargeStruct = type { i32, [1001 x i8], [300 x i32] } 6 7 define i32 @f() nounwind ssp { 8 entry: 9 ; CHECK: f: 10 ; CHECK: ldr 11 ; CHECK: str 12 ; CHECK-NOT:bne 13 %st = alloca %struct.SmallStruct, align 4 14 %call = call i32 @e1(%struct.SmallStruct* byval %st) 15 ret i32 0 16 } 17 18 ; Generate a loop for large struct byval 19 define i32 @g() nounwind ssp { 20 entry: 21 ; CHECK: g: 22 ; CHECK: ldr 23 ; CHECK: sub 24 ; CHECK: str 25 ; CHECK: bne 26 %st = alloca %struct.LargeStruct, align 4 27 %call = call i32 @e2(%struct.LargeStruct* byval %st) 28 ret i32 0 29 } 30 31 ; Generate a loop using NEON instructions 32 define i32 @h() nounwind ssp { 33 entry: 34 ; CHECK: h: 35 ; CHECK: vld1 36 ; CHECK: sub 37 ; CHECK: vst1 38 ; CHECK: bne 39 %st = alloca %struct.LargeStruct, align 16 40 %call = call i32 @e3(%struct.LargeStruct* byval align 16 %st) 41 ret i32 0 42 } 43 44 declare i32 @e1(%struct.SmallStruct* nocapture byval %in) nounwind 45 declare i32 @e2(%struct.LargeStruct* nocapture byval %in) nounwind 46 declare i32 @e3(%struct.LargeStruct* nocapture byval align 16 %in) nounwind 47 48 ; rdar://12442472 49 ; We can't do tail call since address of s is passed to the callee and part of 50 ; s is in caller's local frame. 51 define void @f3(%struct.SmallStruct* nocapture byval %s) nounwind optsize { 52 ; CHECK: f3 53 ; CHECK: bl _consumestruct 54 entry: 55 %0 = bitcast %struct.SmallStruct* %s to i8* 56 tail call void @consumestruct(i8* %0, i32 80) optsize 57 ret void 58 } 59 60 define void @f4(%struct.SmallStruct* nocapture byval %s) nounwind optsize { 61 ; CHECK: f4 62 ; CHECK: bl _consumestruct 63 entry: 64 %addr = getelementptr inbounds %struct.SmallStruct* %s, i32 0, i32 0 65 %0 = bitcast i32* %addr to i8* 66 tail call void @consumestruct(i8* %0, i32 80) optsize 67 ret void 68 } 69 70 ; We can do tail call here since s is in the incoming argument area. 71 define void @f5(i32 %a, i32 %b, i32 %c, i32 %d, %struct.SmallStruct* nocapture byval %s) nounwind optsize { 72 ; CHECK: f5 73 ; CHECK: b _consumestruct 74 entry: 75 %0 = bitcast %struct.SmallStruct* %s to i8* 76 tail call void @consumestruct(i8* %0, i32 80) optsize 77 ret void 78 } 79 80 define void @f6(i32 %a, i32 %b, i32 %c, i32 %d, %struct.SmallStruct* nocapture byval %s) nounwind optsize { 81 ; CHECK: f6 82 ; CHECK: b _consumestruct 83 entry: 84 %addr = getelementptr inbounds %struct.SmallStruct* %s, i32 0, i32 0 85 %0 = bitcast i32* %addr to i8* 86 tail call void @consumestruct(i8* %0, i32 80) optsize 87 ret void 88 } 89 90 declare void @consumestruct(i8* nocapture %structp, i32 %structsize) nounwind 91