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 7define i32 @f() nounwind ssp { 8entry: 9; CHECK-LABEL: 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 19define i32 @g() nounwind ssp { 20entry: 21; CHECK-LABEL: 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 32define i32 @h() nounwind ssp { 33entry: 34; CHECK-LABEL: 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 44declare i32 @e1(%struct.SmallStruct* nocapture byval %in) nounwind 45declare i32 @e2(%struct.LargeStruct* nocapture byval %in) nounwind 46declare 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. 51define void @f3(%struct.SmallStruct* nocapture byval %s) nounwind optsize { 52; CHECK: f3 53; CHECK: bl _consumestruct 54entry: 55 %0 = bitcast %struct.SmallStruct* %s to i8* 56 tail call void @consumestruct(i8* %0, i32 80) optsize 57 ret void 58} 59 60define void @f4(%struct.SmallStruct* nocapture byval %s) nounwind optsize { 61; CHECK: f4 62; CHECK: bl _consumestruct 63entry: 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. 71define void @f5(i32 %a, i32 %b, i32 %c, i32 %d, %struct.SmallStruct* nocapture byval %s) nounwind optsize { 72; CHECK: f5 73; CHECK: b _consumestruct 74entry: 75 %0 = bitcast %struct.SmallStruct* %s to i8* 76 tail call void @consumestruct(i8* %0, i32 80) optsize 77 ret void 78} 79 80define void @f6(i32 %a, i32 %b, i32 %c, i32 %d, %struct.SmallStruct* nocapture byval %s) nounwind optsize { 81; CHECK: f6 82; CHECK: b _consumestruct 83entry: 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 90declare void @consumestruct(i8* nocapture %structp, i32 %structsize) nounwind 91