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