1; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic | FileCheck %s \ 2; RUN: --check-prefixes=ALL,GP32,GP32-M 3; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic | FileCheck %s \ 4; RUN: --check-prefixes=ALL,GP32,GP32-M 5; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic | FileCheck %s \ 6; RUN: --check-prefixes=ALL,GP32,GP32-M 7; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -mattr=+micromips -relocation-model=pic | FileCheck %s \ 8; RUN: --check-prefixes=ALL,GP32,GP32-MM,GP32-MMR2 9; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ 10; RUN: --check-prefixes=ALL,GP32,GP32-MM,GP32-MMR6 11; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic | FileCheck %s \ 12; RUN: --check-prefixes=ALL,GP64,N64 13; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic | FileCheck %s \ 14; RUN: --check-prefixes=ALL,GP64,N64 15; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic | FileCheck %s \ 16; RUN: --check-prefixes=ALL,GP64,N64 17; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -target-abi n32 -relocation-model=pic | FileCheck %s \ 18; RUN: --check-prefixes=ALL,GP64,N32 19; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -target-abi n32 -relocation-model=pic | FileCheck %s \ 20; RUN: --check-prefixes=ALL,GP64,N32 21; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -target-abi n32 -relocation-model=pic | FileCheck %s \ 22; RUN: --check-prefixes=ALL,GP64,N32 23 24; Check dynamic stack realignment in functions without variable-sized objects. 25 26declare void @helper_01(i32, i32, i32, i32, ptr) 27 28; O32 ABI 29define void @func_01() { 30entry: 31; GP32-LABEL: func_01: 32 33 ; prologue 34 ; FIXME: We are currently over-allocating stack space. This particular case 35 ; needs a frame of up to between 16 and 512-bytes but currently 36 ; allocates between 1024 and 1536 bytes 37 ; GP32-M: addiu $sp, $sp, -1024 38 ; GP32-MMR2: addiusp -1024 39 ; GP32-MMR6: addiu $sp, $sp, -1024 40 ; GP32: sw $ra, 1020($sp) 41 ; GP32: sw $fp, 1016($sp) 42 ; 43 ; GP32: move $fp, $sp 44 ; GP32: addiu $[[T0:[0-9]+|ra|gp]], $zero, -512 45 ; GP32-NEXT: and $sp, $sp, $[[T0]] 46 47 ; body 48 ; GP32: addiu $[[T1:[0-9]+]], $sp, 512 49 ; GP32-M: sw $[[T1]], 16($sp) 50 ; GP32-MM: sw16 $[[T1]], 16(${{[0-9]+}}) 51 52 ; epilogue 53 ; GP32: move $sp, $fp 54 ; GP32: lw $fp, 1016($sp) 55 ; GP32: lw $ra, 1020($sp) 56 ; GP32-M: addiu $sp, $sp, 1024 57 ; GP32-MMR2: addiusp 1024 58 ; GP32-MMR6: addiu $sp, $sp, 1024 59 60 %a = alloca i32, align 512 61 call void @helper_01(i32 0, i32 0, i32 0, i32 0, ptr %a) 62 ret void 63} 64 65declare void @helper_02(i32, i32, i32, i32, 66 i32, i32, i32, i32, ptr) 67 68; N32/N64 ABIs 69define void @func_02() { 70entry: 71; GP64-LABEL: func_02: 72 73 ; prologue 74 ; FIXME: We are currently over-allocating stack space. This particular case 75 ; needs a frame of up to between 16 and 512-bytes but currently 76 ; allocates between 1024 and 1536 bytes 77 ; N32: addiu $sp, $sp, -1024 78 ; N64: daddiu $sp, $sp, -1024 79 ; GP64: sd $ra, 1016($sp) 80 ; GP64: sd $fp, 1008($sp) 81 ; N32: sd $gp, 1000($sp) 82 ; 83 ; GP64: move $fp, $sp 84 ; N32: addiu $[[T0:[0-9]+|ra]], $zero, -512 85 ; N64: daddiu $[[T0:[0-9]+|ra]], $zero, -512 86 ; GP64-NEXT: and $sp, $sp, $[[T0]] 87 88 ; body 89 ; N32: addiu $[[T1:[0-9]+]], $sp, 512 90 ; N64: daddiu $[[T1:[0-9]+]], $sp, 512 91 ; GP64: sd $[[T1]], 0($sp) 92 93 ; epilogue 94 ; GP64: move $sp, $fp 95 ; N32: ld $gp, 1000($sp) 96 ; GP64: ld $fp, 1008($sp) 97 ; GP64: ld $ra, 1016($sp) 98 ; N32: addiu $sp, $sp, 1024 99 ; N64: daddiu $sp, $sp, 1024 100 101 %a = alloca i32, align 512 102 call void @helper_02(i32 0, i32 0, i32 0, i32 0, 103 i32 0, i32 0, i32 0, i32 0, ptr %a) 104 ret void 105} 106 107; Verify that we use $fp for referencing incoming arguments. 108 109declare void @helper_03(i32, i32, i32, i32, ptr, ptr) 110 111; O32 ABI 112define void @func_03(i32 %p0, i32 %p1, i32 %p2, i32 %p3, ptr %b) { 113entry: 114; GP32-LABEL: func_03: 115 116 ; body 117 ; FIXME: We are currently over-allocating stack space. 118 ; GP32-DAG: addiu $[[T0:[0-9]+]], $sp, 512 119 ; GP32-M-DAG: sw $[[T0]], 16($sp) 120 ; GP32-MM-DAG: sw16 $[[T0]], 16(${{[0-9]+}}) 121 ; GP32-DAG: lw $[[T1:[0-9]+]], 1040($fp) 122 ; GP32-M-DAG: sw $[[T1]], 20($sp) 123 ; GP32-MM-DAG: sw16 $[[T1]], 20(${{[0-9]+}}) 124 125 %a = alloca i32, align 512 126 call void @helper_03(i32 0, i32 0, i32 0, i32 0, ptr %a, ptr %b) 127 ret void 128} 129 130declare void @helper_04(i32, i32, i32, i32, 131 i32, i32, i32, i32, ptr, ptr) 132 133; N32/N64 ABIs 134define void @func_04(i32 %p0, i32 %p1, i32 %p2, i32 %p3, 135 i32 %p4, i32 %p5, i32 %p6, i32 %p7, 136 ptr %b) { 137entry: 138; GP64-LABEL: func_04: 139 140 ; body 141 ; FIXME: We are currently over-allocating stack space. 142 ; N32-DAG: addiu $[[T0:[0-9]+]], $sp, 512 143 ; N64-DAG: daddiu $[[T0:[0-9]+]], $sp, 512 144 ; GP64-DAG: sd $[[T0]], 0($sp) 145 ; GP64-DAG: ld $[[T1:[0-9]+]], 1024($fp) 146 ; GP64-DAG: sd $[[T1]], 8($sp) 147 148 %a = alloca i32, align 512 149 call void @helper_04(i32 0, i32 0, i32 0, i32 0, 150 i32 0, i32 0, i32 0, i32 0, ptr %a, ptr %b) 151 ret void 152} 153 154; Check dynamic stack realignment in functions with variable-sized objects. 155 156; O32 ABI 157define void @func_05(i32 %sz) { 158entry: 159; GP32-LABEL: func_05: 160 161 ; prologue 162 ; FIXME: We are currently over-allocating stack space. 163 ; GP32-M: addiu $sp, $sp, -1024 164 ; GP32-MMR2: addiusp -1024 165 ; GP32-MMR6: addiu $sp, $sp, -1024 166 ; GP32: sw $ra, 1020($sp) 167 ; GP32: sw $fp, 1016($sp) 168 ; GP32: sw $23, 1012($sp) 169 ; 170 ; GP32: move $fp, $sp 171 ; GP32: addiu $[[T0:[0-9]+|gp]], $zero, -512 172 ; GP32-NEXT: and $sp, $sp, $[[T0]] 173 ; GP32-NEXT: move $23, $sp 174 175 ; body 176 ; GP32: addiu $[[T1:[0-9]+]], $zero, 222 177 ; GP32: sw $[[T1]], 508($23) 178 179 ; epilogue 180 ; GP32: move $sp, $fp 181 ; GP32: lw $23, 1012($sp) 182 ; GP32: lw $fp, 1016($sp) 183 ; GP32: lw $ra, 1020($sp) 184 ; GP32-M: addiu $sp, $sp, 1024 185 ; GP32-MMR2: addiusp 1024 186 ; GP32-MMR6: addiu $sp, $sp, 1024 187 188 %a0 = alloca i32, i32 %sz, align 512 189 %a1 = alloca i32, align 4 190 191 store volatile i32 111, ptr %a0, align 512 192 store volatile i32 222, ptr %a1, align 4 193 194 ret void 195} 196 197; N32/N64 ABIs 198define void @func_06(i32 %sz) { 199entry: 200; GP64-LABEL: func_06: 201 202 ; prologue 203 ; FIXME: We are currently over-allocating stack space. 204 ; N32: addiu $sp, $sp, -1024 205 ; N64: daddiu $sp, $sp, -1024 206 ; GP64: sd $ra, 1016($sp) 207 ; GP64: sd $fp, 1008($sp) 208 ; GP64: sd $23, 1000($sp) 209 ; 210 ; GP64: move $fp, $sp 211 ; GP64: addiu $[[T0:[0-9]+|gp]], $zero, -512 212 ; GP64-NEXT: and $sp, $sp, $[[T0]] 213 ; GP64-NEXT: move $23, $sp 214 215 ; body 216 ; GP64: addiu $[[T1:[0-9]+]], $zero, 222 217 ; GP64: sw $[[T1]], 508($23) 218 219 ; epilogue 220 ; GP64: move $sp, $fp 221 ; GP64: ld $23, 1000($sp) 222 ; GP64: ld $fp, 1008($sp) 223 ; GP64: ld $ra, 1016($sp) 224 ; N32: addiu $sp, $sp, 1024 225 ; N64: daddiu $sp, $sp, 1024 226 227 %a0 = alloca i32, i32 %sz, align 512 228 %a1 = alloca i32, align 4 229 230 store volatile i32 111, ptr %a0, align 512 231 store volatile i32 222, ptr %a1, align 4 232 233 ret void 234} 235 236; Verify that we use $fp for referencing incoming arguments and $sp for 237; building outbound arguments for nested function calls. 238 239; O32 ABI 240define void @func_07(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %sz) { 241entry: 242; GP32-LABEL: func_07: 243 244 ; body 245 ; FIXME: We are currently over-allocating stack space. 246 ; GP32-DAG: lw $[[T0:[0-9]+]], 1040($fp) 247 ; 248 ; GP32-DAG: addiu $[[T1:[0-9]+]], $zero, 222 249 ; GP32-DAG: sw $[[T1]], 508($23) 250 ; 251 ; GP32-M-DAG: sw $[[T2:[0-9]+]], 16($sp) 252 ; GP32-MM-DAG: sw16 $[[T2:[0-9]+]], 16($[[T3:[0-9]+]]) 253 254 %a0 = alloca i32, i32 %sz, align 512 255 %a1 = alloca i32, align 4 256 257 store volatile i32 111, ptr %a0, align 512 258 store volatile i32 222, ptr %a1, align 4 259 260 call void @helper_01(i32 0, i32 0, i32 0, i32 0, ptr %a1) 261 262 ret void 263} 264 265; N32/N64 ABIs 266define void @func_08(i32 %p0, i32 %p1, i32 %p2, i32 %p3, 267 i32 %p4, i32 %p5, i32 %p6, i32 %p7, 268 i32 %sz) { 269entry: 270; GP64-LABEL: func_08: 271 272 ; body 273 ; FIXME: We are currently over-allocating stack space. 274 ; N32-DAG: lw $[[T0:[0-9]+]], 1028($fp) 275 ; N64-DAG: lwu $[[T0:[0-9]+]], 1028($fp) 276 ; 277 ; GP64-DAG: addiu $[[T1:[0-9]+]], $zero, 222 278 ; GP64-DAG: sw $[[T1]], 508($23) 279 ; 280 ; GP64-DAG: sd $[[T2:[0-9]+]], 0($sp) 281 282 %a0 = alloca i32, i32 %sz, align 512 283 %a1 = alloca i32, align 4 284 285 store volatile i32 111, ptr %a0, align 512 286 store volatile i32 222, ptr %a1, align 4 287 288 call void @helper_02(i32 0, i32 0, i32 0, i32 0, 289 i32 0, i32 0, i32 0, i32 0, ptr %a1) 290 ret void 291} 292 293; Check that we do not perform dynamic stack realignment in the presence of 294; the "no-realign-stack" function attribute. 295define void @func_09() "no-realign-stack" { 296entry: 297; ALL-LABEL: func_09: 298 299 ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] 300 301 %a = alloca i32, align 512 302 call void @helper_01(i32 0, i32 0, i32 0, i32 0, ptr %a) 303 ret void 304} 305 306define void @func_10(i32 %sz) "no-realign-stack" { 307entry: 308; ALL-LABEL: func_10: 309 310 ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] 311 312 %a0 = alloca i32, i32 %sz, align 512 313 %a1 = alloca i32, align 4 314 315 store volatile i32 111, ptr %a0, align 512 316 store volatile i32 222, ptr %a1, align 4 317 318 ret void 319} 320