1; RUN: llc -mtriple=thumbv4t-none--eabi < %s | FileCheck %s --check-prefix=CHECK-V4T 2; RUN: llc -mtriple=thumbv5t-none--eabi < %s | FileCheck %s --check-prefix=CHECK-V5T 3 4; CHECK-V4T-LABEL: clobberframe 5; CHECK-V5T-LABEL: clobberframe 6define <4 x i32> @clobberframe() #0 { 7entry: 8; Prologue 9; -------- 10; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr} 11; CHECK-V4T: sub sp, 12; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr} 13 14 %b = alloca <4 x i32>, align 16 15 %a = alloca <4 x i32>, align 16 16 store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16 17 store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16 18 %0 = load <4 x i32>* %a, align 16 19 ret <4 x i32> %0 20 21; Epilogue 22; -------- 23; CHECK-V4T: add sp, 24; CHECK-V4T-NEXT: pop {[[SAVED]]} 25; CHECK-V4T-NEXT: mov r12, r3 26; CHECK-V4T-NEXT: pop {r3} 27; CHECK-V4T-NEXT: mov lr, r3 28; CHECK-V4T-NEXT: mov r3, r12 29; CHECK-V4T: bx lr 30; CHECK-V5T: pop {[[SAVED]], pc} 31} 32 33; CHECK-V4T-LABEL: clobbervariadicframe 34; CHECK-V5T-LABEL: clobbervariadicframe 35define <4 x i32> @clobbervariadicframe(i32 %i, ...) #0 { 36entry: 37; Prologue 38; -------- 39; CHECK-V4T: sub sp, 40; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr} 41; CHECK-V5T: sub sp, 42; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr} 43 44 %b = alloca <4 x i32>, align 16 45 %a = alloca <4 x i32>, align 16 46 store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16 47 store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16 48 %0 = load <4 x i32>* %a, align 16 49 call void @llvm.va_start(i8* null) 50 ret <4 x i32> %0 51 52; Epilogue 53; -------- 54; CHECK-V4T: pop {[[SAVED]]} 55; CHECK-V4T-NEXT: mov r12, r3 56; CHECK-V4T-NEXT: pop {r3} 57; CHECK-V4T-NEXT: add sp, 58; CHECK-V4T-NEXT: mov lr, r3 59; CHECK-V4T-NEXT: mov r3, r12 60; CHECK-V4T: bx lr 61; CHECK-V5T: add sp, 62; CHECK-V5T-NEXT: pop {[[SAVED]]} 63; CHECK-V5T-NEXT: mov r12, r3 64; CHECK-V5T-NEXT: pop {r3} 65; CHECK-V5T-NEXT: add sp, 66; CHECK-V5T-NEXT: mov lr, r3 67; CHECK-V5T-NEXT: mov r3, r12 68; CHECK-V5T-NEXT: bx lr 69} 70 71; CHECK-V4T-LABEL: simpleframe 72; CHECK-V5T-LABEL: simpleframe 73define i32 @simpleframe() #0 { 74entry: 75; Prologue 76; -------- 77; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr} 78; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr} 79 80 %a = alloca i32, align 4 81 %b = alloca i32, align 4 82 %c = alloca i32, align 4 83 %d = alloca i32, align 4 84 store i32 1, i32* %a, align 4 85 store i32 2, i32* %b, align 4 86 store i32 3, i32* %c, align 4 87 store i32 4, i32* %d, align 4 88 %0 = load i32* %a, align 4 89 %inc = add nsw i32 %0, 1 90 store i32 %inc, i32* %a, align 4 91 %1 = load i32* %b, align 4 92 %inc1 = add nsw i32 %1, 1 93 store i32 %inc1, i32* %b, align 4 94 %2 = load i32* %c, align 4 95 %inc2 = add nsw i32 %2, 1 96 store i32 %inc2, i32* %c, align 4 97 %3 = load i32* %d, align 4 98 %inc3 = add nsw i32 %3, 1 99 store i32 %inc3, i32* %d, align 4 100 %4 = load i32* %a, align 4 101 %5 = load i32* %b, align 4 102 %add = add nsw i32 %4, %5 103 %6 = load i32* %c, align 4 104 %add4 = add nsw i32 %add, %6 105 %7 = load i32* %d, align 4 106 %add5 = add nsw i32 %add4, %7 107 ret i32 %add5 108 109; Epilogue 110; -------- 111; CHECK-V4T: pop {[[SAVED]]} 112; CHECK-V4T: pop {r3} 113; CHECK-V4T: bx r3 114; CHECK-V5T: pop {[[SAVED]], pc} 115} 116 117; CHECK-V4T-LABEL: simplevariadicframe 118; CHECK-V5T-LABEL: simplevariadicframe 119define i32 @simplevariadicframe(i32 %i, ...) #0 { 120entry: 121; Prologue 122; -------- 123; CHECK-V4T: sub sp, 124; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr} 125; CHECK-V4T: sub sp, 126; CHECK-V5T: sub sp, 127; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr} 128; CHECK-V5T: sub sp, 129 130 %a = alloca i32, align 4 131 %b = alloca i32, align 4 132 %c = alloca i32, align 4 133 %d = alloca i32, align 4 134 store i32 1, i32* %a, align 4 135 store i32 2, i32* %b, align 4 136 store i32 3, i32* %c, align 4 137 store i32 4, i32* %d, align 4 138 %0 = load i32* %a, align 4 139 %inc = add nsw i32 %0, 1 140 store i32 %inc, i32* %a, align 4 141 %1 = load i32* %b, align 4 142 %inc1 = add nsw i32 %1, 1 143 store i32 %inc1, i32* %b, align 4 144 %2 = load i32* %c, align 4 145 %inc2 = add nsw i32 %2, 1 146 store i32 %inc2, i32* %c, align 4 147 %3 = load i32* %d, align 4 148 %inc3 = add nsw i32 %3, 1 149 store i32 %inc3, i32* %d, align 4 150 %4 = load i32* %a, align 4 151 %5 = load i32* %b, align 4 152 %add = add nsw i32 %4, %5 153 %6 = load i32* %c, align 4 154 %add4 = add nsw i32 %add, %6 155 %7 = load i32* %d, align 4 156 %add5 = add nsw i32 %add4, %7 157 %add6 = add nsw i32 %add5, %i 158 call void @llvm.va_start(i8* null) 159 ret i32 %add6 160 161; Epilogue 162; -------- 163; CHECK-V4T: add sp, 164; CHECK-V4T-NEXT: pop {[[SAVED]]} 165; CHECK-V4T-NEXT: pop {r3} 166; CHECK-V4T-NEXT: add sp, 167; CHECK-V4T-NEXT: bx r3 168; CHECK-V5T: add sp, 169; CHECK-V5T-NEXT: pop {[[SAVED]]} 170; CHECK-V5T-NEXT: pop {r3} 171; CHECK-V5T-NEXT: add sp, 172; CHECK-V5T-NEXT: bx r3 173} 174 175; CHECK-V4T-LABEL: noframe 176; CHECK-V5T-LABEL: noframe 177define i32 @noframe() #0 { 178entry: 179; Prologue 180; -------- 181; CHECK-V4T-NOT: push 182; CHECK-V5T-NOT: push 183 ret i32 0; 184; Epilogue 185; -------- 186; CHECK-V4T-NOT: pop 187; CHECK-V5T-NOT: pop 188; CHECK-V4T: bx lr 189; CHECK-V5T: bx lr 190} 191 192; CHECK-V4T-LABEL: novariadicframe 193; CHECK-V5T-LABEL: novariadicframe 194define i32 @novariadicframe(i32 %i, ...) #0 { 195entry: 196; Prologue 197; -------- 198; CHECK-V4T: sub sp, 199; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr} 200; CHECK-V5T: sub sp, 201; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr} 202 203 call void @llvm.va_start(i8* null) 204 ret i32 %i; 205; Epilogue 206; -------- 207; CHECK-V4T: pop {[[SAVED]]} 208; CHECK-V4T-NEXT: pop {r3} 209; CHECK-V4T-NEXT: add sp, 210; CHECK-V4T-NEXT: bx r3 211; CHECK-V5T: pop {[[SAVED]]} 212; CHECK-V5T-NEXT: pop {r3} 213; CHECK-V5T-NEXT: add sp, 214; CHECK-V5T-NEXT: bx r3 215} 216 217declare void @llvm.va_start(i8*) nounwind 218