1 ; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -verify-machineinstrs | FileCheck %s -check-prefix=X32-Linux 2 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -verify-machineinstrs | FileCheck %s -check-prefix=X64-Linux 3 ; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X32-Darwin 4 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X64-Darwin 5 ; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -verify-machineinstrs | FileCheck %s -check-prefix=X32-MinGW 6 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -verify-machineinstrs | FileCheck %s -check-prefix=X64-FreeBSD 7 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -verify-machineinstrs | FileCheck %s -check-prefix=X64-MinGW 8 9 ; We used to crash with filetype=obj 10 ; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -filetype=obj 11 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -filetype=obj 12 ; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -filetype=obj 13 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -filetype=obj 14 ; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -filetype=obj 15 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -filetype=obj 16 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -filetype=obj 17 18 ; RUN: not llc < %s -mcpu=generic -mtriple=x86_64-solaris 2> %t.log 19 ; RUN: FileCheck %s -input-file=%t.log -check-prefix=X64-Solaris 20 ; RUN: not llc < %s -mcpu=generic -mtriple=i686-freebsd 2> %t.log 21 ; RUN: FileCheck %s -input-file=%t.log -check-prefix=X32-FreeBSD 22 23 ; X64-Solaris: Segmented stacks not supported on this platform 24 ; X32-FreeBSD: Segmented stacks not supported on FreeBSD i386 25 26 ; Just to prevent the alloca from being optimized away 27 declare void @dummy_use(i32*, i32) 28 29 define void @test_basic() #0 { 30 %mem = alloca i32, i32 10 31 call void @dummy_use (i32* %mem, i32 10) 32 ret void 33 34 ; X32-Linux-LABEL: test_basic: 35 36 ; X32-Linux: cmpl %gs:48, %esp 37 ; X32-Linux-NEXT: ja .LBB0_2 38 39 ; X32-Linux: pushl $0 40 ; X32-Linux-NEXT: pushl $60 41 ; X32-Linux-NEXT: calll __morestack 42 ; X32-Linux-NEXT: ret 43 44 ; X64-Linux-LABEL: test_basic: 45 46 ; X64-Linux: cmpq %fs:112, %rsp 47 ; X64-Linux-NEXT: ja .LBB0_2 48 49 ; X64-Linux: movabsq $40, %r10 50 ; X64-Linux-NEXT: movabsq $0, %r11 51 ; X64-Linux-NEXT: callq __morestack 52 ; X64-Linux-NEXT: ret 53 54 ; X32-Darwin-LABEL: test_basic: 55 56 ; X32-Darwin: movl $432, %ecx 57 ; X32-Darwin-NEXT: cmpl %gs:(%ecx), %esp 58 ; X32-Darwin-NEXT: ja LBB0_2 59 60 ; X32-Darwin: pushl $0 61 ; X32-Darwin-NEXT: pushl $60 62 ; X32-Darwin-NEXT: calll ___morestack 63 ; X32-Darwin-NEXT: ret 64 65 ; X64-Darwin-LABEL: test_basic: 66 67 ; X64-Darwin: cmpq %gs:816, %rsp 68 ; X64-Darwin-NEXT: ja LBB0_2 69 70 ; X64-Darwin: movabsq $40, %r10 71 ; X64-Darwin-NEXT: movabsq $0, %r11 72 ; X64-Darwin-NEXT: callq ___morestack 73 ; X64-Darwin-NEXT: ret 74 75 ; X32-MinGW-LABEL: test_basic: 76 77 ; X32-MinGW: cmpl %fs:20, %esp 78 ; X32-MinGW-NEXT: ja LBB0_2 79 80 ; X32-MinGW: pushl $0 81 ; X32-MinGW-NEXT: pushl $48 82 ; X32-MinGW-NEXT: calll ___morestack 83 ; X32-MinGW-NEXT: ret 84 85 ; X64-MinGW-LABEL: test_basic: 86 87 ; X64-MinGW: cmpq %gs:40, %rsp 88 ; X64-MinGW-NEXT: ja .LBB0_2 89 90 ; X64-MinGW: movabsq $72, %r10 91 ; X64-MinGW-NEXT: movabsq $32, %r11 92 ; X64-MinGW-NEXT: callq __morestack 93 ; X64-MinGW-NEXT: retq 94 95 ; X64-FreeBSD-LABEL: test_basic: 96 97 ; X64-FreeBSD: cmpq %fs:24, %rsp 98 ; X64-FreeBSD-NEXT: ja .LBB0_2 99 100 ; X64-FreeBSD: movabsq $40, %r10 101 ; X64-FreeBSD-NEXT: movabsq $0, %r11 102 ; X64-FreeBSD-NEXT: callq __morestack 103 ; X64-FreeBSD-NEXT: ret 104 105 } 106 107 define i32 @test_nested(i32 * nest %closure, i32 %other) #0 { 108 %addend = load i32 * %closure 109 %result = add i32 %other, %addend 110 %mem = alloca i32, i32 10 111 call void @dummy_use (i32* %mem, i32 10) 112 ret i32 %result 113 114 ; X32-Linux: cmpl %gs:48, %esp 115 ; X32-Linux-NEXT: ja .LBB1_2 116 117 ; X32-Linux: pushl $4 118 ; X32-Linux-NEXT: pushl $60 119 ; X32-Linux-NEXT: calll __morestack 120 ; X32-Linux-NEXT: ret 121 122 ; X64-Linux: cmpq %fs:112, %rsp 123 ; X64-Linux-NEXT: ja .LBB1_2 124 125 ; X64-Linux: movq %r10, %rax 126 ; X64-Linux-NEXT: movabsq $56, %r10 127 ; X64-Linux-NEXT: movabsq $0, %r11 128 ; X64-Linux-NEXT: callq __morestack 129 ; X64-Linux-NEXT: ret 130 ; X64-Linux-NEXT: movq %rax, %r10 131 132 ; X32-Darwin: movl $432, %edx 133 ; X32-Darwin-NEXT: cmpl %gs:(%edx), %esp 134 ; X32-Darwin-NEXT: ja LBB1_2 135 136 ; X32-Darwin: pushl $4 137 ; X32-Darwin-NEXT: pushl $60 138 ; X32-Darwin-NEXT: calll ___morestack 139 ; X32-Darwin-NEXT: ret 140 141 ; X64-Darwin: cmpq %gs:816, %rsp 142 ; X64-Darwin-NEXT: ja LBB1_2 143 144 ; X64-Darwin: movq %r10, %rax 145 ; X64-Darwin-NEXT: movabsq $56, %r10 146 ; X64-Darwin-NEXT: movabsq $0, %r11 147 ; X64-Darwin-NEXT: callq ___morestack 148 ; X64-Darwin-NEXT: ret 149 ; X64-Darwin-NEXT: movq %rax, %r10 150 151 ; X32-MinGW: cmpl %fs:20, %esp 152 ; X32-MinGW-NEXT: ja LBB1_2 153 154 ; X32-MinGW: pushl $4 155 ; X32-MinGW-NEXT: pushl $52 156 ; X32-MinGW-NEXT: calll ___morestack 157 ; X32-MinGW-NEXT: ret 158 159 ; X64-MinGW-LABEL: test_nested: 160 ; X64-MinGW: cmpq %gs:40, %rsp 161 ; X64-MinGW-NEXT: ja .LBB1_2 162 163 ; X64-MinGW: movq %r10, %rax 164 ; X64-MinGW-NEXT: movabsq $88, %r10 165 ; X64-MinGW-NEXT: movabsq $32, %r11 166 ; X64-MinGW-NEXT: callq __morestack 167 ; X64-MinGW-NEXT: retq 168 ; X64-MinGW-NEXT: movq %rax, %r10 169 170 ; X64-FreeBSD: cmpq %fs:24, %rsp 171 ; X64-FreeBSD-NEXT: ja .LBB1_2 172 173 ; X64-FreeBSD: movq %r10, %rax 174 ; X64-FreeBSD-NEXT: movabsq $56, %r10 175 ; X64-FreeBSD-NEXT: movabsq $0, %r11 176 ; X64-FreeBSD-NEXT: callq __morestack 177 ; X64-FreeBSD-NEXT: ret 178 ; X64-FreeBSD-NEXT: movq %rax, %r10 179 180 } 181 182 define void @test_large() #0 { 183 %mem = alloca i32, i32 10000 184 call void @dummy_use (i32* %mem, i32 0) 185 ret void 186 187 ; X32-Linux: leal -40012(%esp), %ecx 188 ; X32-Linux-NEXT: cmpl %gs:48, %ecx 189 ; X32-Linux-NEXT: ja .LBB2_2 190 191 ; X32-Linux: pushl $0 192 ; X32-Linux-NEXT: pushl $40012 193 ; X32-Linux-NEXT: calll __morestack 194 ; X32-Linux-NEXT: ret 195 196 ; X64-Linux: leaq -40008(%rsp), %r11 197 ; X64-Linux-NEXT: cmpq %fs:112, %r11 198 ; X64-Linux-NEXT: ja .LBB2_2 199 200 ; X64-Linux: movabsq $40008, %r10 201 ; X64-Linux-NEXT: movabsq $0, %r11 202 ; X64-Linux-NEXT: callq __morestack 203 ; X64-Linux-NEXT: ret 204 205 ; X32-Darwin: leal -40012(%esp), %ecx 206 ; X32-Darwin-NEXT: movl $432, %eax 207 ; X32-Darwin-NEXT: cmpl %gs:(%eax), %ecx 208 ; X32-Darwin-NEXT: ja LBB2_2 209 210 ; X32-Darwin: pushl $0 211 ; X32-Darwin-NEXT: pushl $40012 212 ; X32-Darwin-NEXT: calll ___morestack 213 ; X32-Darwin-NEXT: ret 214 215 ; X64-Darwin: leaq -40008(%rsp), %r11 216 ; X64-Darwin-NEXT: cmpq %gs:816, %r11 217 ; X64-Darwin-NEXT: ja LBB2_2 218 219 ; X64-Darwin: movabsq $40008, %r10 220 ; X64-Darwin-NEXT: movabsq $0, %r11 221 ; X64-Darwin-NEXT: callq ___morestack 222 ; X64-Darwin-NEXT: ret 223 224 ; X32-MinGW: leal -40008(%esp), %ecx 225 ; X32-MinGW-NEXT: cmpl %fs:20, %ecx 226 ; X32-MinGW-NEXT: ja LBB2_2 227 228 ; X32-MinGW: pushl $0 229 ; X32-MinGW-NEXT: pushl $40008 230 ; X32-MinGW-NEXT: calll ___morestack 231 ; X32-MinGW-NEXT: ret 232 233 ; X64-MinGW-LABEL: test_large: 234 ; X64-MinGW: leaq -40040(%rsp), %r11 235 ; X64-MinGW-NEXT: cmpq %gs:40, %r11 236 ; X64-MinGW-NEXT: ja .LBB2_2 237 238 ; X64-MinGW: movabsq $40040, %r10 239 ; X64-MinGW-NEXT: movabsq $32, %r11 240 ; X64-MinGW-NEXT: callq __morestack 241 ; X64-MinGW-NEXT: retq 242 243 ; X64-FreeBSD: leaq -40008(%rsp), %r11 244 ; X64-FreeBSD-NEXT: cmpq %fs:24, %r11 245 ; X64-FreeBSD-NEXT: ja .LBB2_2 246 247 ; X64-FreeBSD: movabsq $40008, %r10 248 ; X64-FreeBSD-NEXT: movabsq $0, %r11 249 ; X64-FreeBSD-NEXT: callq __morestack 250 ; X64-FreeBSD-NEXT: ret 251 252 } 253 254 define fastcc void @test_fastcc() #0 { 255 %mem = alloca i32, i32 10 256 call void @dummy_use (i32* %mem, i32 10) 257 ret void 258 259 ; X32-Linux-LABEL: test_fastcc: 260 261 ; X32-Linux: cmpl %gs:48, %esp 262 ; X32-Linux-NEXT: ja .LBB3_2 263 264 ; X32-Linux: pushl $0 265 ; X32-Linux-NEXT: pushl $60 266 ; X32-Linux-NEXT: calll __morestack 267 ; X32-Linux-NEXT: ret 268 269 ; X64-Linux-LABEL: test_fastcc: 270 271 ; X64-Linux: cmpq %fs:112, %rsp 272 ; X64-Linux-NEXT: ja .LBB3_2 273 274 ; X64-Linux: movabsq $40, %r10 275 ; X64-Linux-NEXT: movabsq $0, %r11 276 ; X64-Linux-NEXT: callq __morestack 277 ; X64-Linux-NEXT: ret 278 279 ; X32-Darwin-LABEL: test_fastcc: 280 281 ; X32-Darwin: movl $432, %eax 282 ; X32-Darwin-NEXT: cmpl %gs:(%eax), %esp 283 ; X32-Darwin-NEXT: ja LBB3_2 284 285 ; X32-Darwin: pushl $0 286 ; X32-Darwin-NEXT: pushl $60 287 ; X32-Darwin-NEXT: calll ___morestack 288 ; X32-Darwin-NEXT: ret 289 290 ; X64-Darwin-LABEL: test_fastcc: 291 292 ; X64-Darwin: cmpq %gs:816, %rsp 293 ; X64-Darwin-NEXT: ja LBB3_2 294 295 ; X64-Darwin: movabsq $40, %r10 296 ; X64-Darwin-NEXT: movabsq $0, %r11 297 ; X64-Darwin-NEXT: callq ___morestack 298 ; X64-Darwin-NEXT: ret 299 300 ; X32-MinGW-LABEL: test_fastcc: 301 302 ; X32-MinGW: cmpl %fs:20, %esp 303 ; X32-MinGW-NEXT: ja LBB3_2 304 305 ; X32-MinGW: pushl $0 306 ; X32-MinGW-NEXT: pushl $48 307 ; X32-MinGW-NEXT: calll ___morestack 308 ; X32-MinGW-NEXT: ret 309 310 ; X64-MinGW-LABEL: test_fastcc: 311 312 ; X64-MinGW: cmpq %gs:40, %rsp 313 ; X64-MinGW-NEXT: ja .LBB3_2 314 315 ; X64-MinGW: movabsq $72, %r10 316 ; X64-MinGW-NEXT: movabsq $32, %r11 317 ; X64-MinGW-NEXT: callq __morestack 318 ; X64-MinGW-NEXT: retq 319 320 ; X64-FreeBSD-LABEL: test_fastcc: 321 322 ; X64-FreeBSD: cmpq %fs:24, %rsp 323 ; X64-FreeBSD-NEXT: ja .LBB3_2 324 325 ; X64-FreeBSD: movabsq $40, %r10 326 ; X64-FreeBSD-NEXT: movabsq $0, %r11 327 ; X64-FreeBSD-NEXT: callq __morestack 328 ; X64-FreeBSD-NEXT: ret 329 330 } 331 332 define fastcc void @test_fastcc_large() #0 { 333 %mem = alloca i32, i32 10000 334 call void @dummy_use (i32* %mem, i32 0) 335 ret void 336 337 ; X32-Linux-LABEL: test_fastcc_large: 338 339 ; X32-Linux: leal -40012(%esp), %eax 340 ; X32-Linux-NEXT: cmpl %gs:48, %eax 341 ; X32-Linux-NEXT: ja .LBB4_2 342 343 ; X32-Linux: pushl $0 344 ; X32-Linux-NEXT: pushl $40012 345 ; X32-Linux-NEXT: calll __morestack 346 ; X32-Linux-NEXT: ret 347 348 ; X64-Linux-LABEL: test_fastcc_large: 349 350 ; X64-Linux: leaq -40008(%rsp), %r11 351 ; X64-Linux-NEXT: cmpq %fs:112, %r11 352 ; X64-Linux-NEXT: ja .LBB4_2 353 354 ; X64-Linux: movabsq $40008, %r10 355 ; X64-Linux-NEXT: movabsq $0, %r11 356 ; X64-Linux-NEXT: callq __morestack 357 ; X64-Linux-NEXT: ret 358 359 ; X32-Darwin-LABEL: test_fastcc_large: 360 361 ; X32-Darwin: leal -40012(%esp), %eax 362 ; X32-Darwin-NEXT: movl $432, %ecx 363 ; X32-Darwin-NEXT: cmpl %gs:(%ecx), %eax 364 ; X32-Darwin-NEXT: ja LBB4_2 365 366 ; X32-Darwin: pushl $0 367 ; X32-Darwin-NEXT: pushl $40012 368 ; X32-Darwin-NEXT: calll ___morestack 369 ; X32-Darwin-NEXT: ret 370 371 ; X64-Darwin-LABEL: test_fastcc_large: 372 373 ; X64-Darwin: leaq -40008(%rsp), %r11 374 ; X64-Darwin-NEXT: cmpq %gs:816, %r11 375 ; X64-Darwin-NEXT: ja LBB4_2 376 377 ; X64-Darwin: movabsq $40008, %r10 378 ; X64-Darwin-NEXT: movabsq $0, %r11 379 ; X64-Darwin-NEXT: callq ___morestack 380 ; X64-Darwin-NEXT: ret 381 382 ; X32-MinGW-LABEL: test_fastcc_large: 383 384 ; X32-MinGW: leal -40008(%esp), %eax 385 ; X32-MinGW-NEXT: cmpl %fs:20, %eax 386 ; X32-MinGW-NEXT: ja LBB4_2 387 388 ; X32-MinGW: pushl $0 389 ; X32-MinGW-NEXT: pushl $40008 390 ; X32-MinGW-NEXT: calll ___morestack 391 ; X32-MinGW-NEXT: ret 392 393 ; X64-MinGW-LABEL: test_fastcc_large: 394 395 ; X64-MinGW: leaq -40040(%rsp), %r11 396 ; X64-MinGW-NEXT: cmpq %gs:40, %r11 397 ; X64-MinGW-NEXT: ja .LBB4_2 398 399 ; X64-MinGW: movabsq $40040, %r10 400 ; X64-MinGW-NEXT: movabsq $32, %r11 401 ; X64-MinGW-NEXT: callq __morestack 402 ; X64-MinGW-NEXT: retq 403 404 ; X64-FreeBSD-LABEL: test_fastcc_large: 405 406 ; X64-FreeBSD: leaq -40008(%rsp), %r11 407 ; X64-FreeBSD-NEXT: cmpq %fs:24, %r11 408 ; X64-FreeBSD-NEXT: ja .LBB4_2 409 410 ; X64-FreeBSD: movabsq $40008, %r10 411 ; X64-FreeBSD-NEXT: movabsq $0, %r11 412 ; X64-FreeBSD-NEXT: callq __morestack 413 ; X64-FreeBSD-NEXT: ret 414 415 } 416 417 define fastcc void @test_fastcc_large_with_ecx_arg(i32 %a) #0 { 418 %mem = alloca i32, i32 10000 419 call void @dummy_use (i32* %mem, i32 %a) 420 ret void 421 422 ; This is testing that the Mac implementation preserves ecx 423 424 ; X32-Darwin-LABEL: test_fastcc_large_with_ecx_arg: 425 426 ; X32-Darwin: leal -40012(%esp), %eax 427 ; X32-Darwin-NEXT: pushl %ecx 428 ; X32-Darwin-NEXT: movl $432, %ecx 429 ; X32-Darwin-NEXT: cmpl %gs:(%ecx), %eax 430 ; X32-Darwin-NEXT: popl %ecx 431 ; X32-Darwin-NEXT: ja LBB5_2 432 433 ; X32-Darwin: pushl $0 434 ; X32-Darwin-NEXT: pushl $40012 435 ; X32-Darwin-NEXT: calll ___morestack 436 ; X32-Darwin-NEXT: ret 437 438 } 439 440 define void @test_nostack() #0 { 441 ret void 442 443 ; X32-Linux-LABEL: test_nostack: 444 ; X32-Linux-NOT: calll __morestack 445 446 ; X64-Linux-LABEL: test_nostack: 447 ; X32-Linux-NOT: callq __morestack 448 449 ; X32-Darwin-LABEL: test_nostack: 450 ; X32-Darwin-NOT: calll __morestack 451 452 ; X64-Darwin-LABEL: test_nostack: 453 ; X64-Darwin-NOT: callq __morestack 454 455 ; X32-MinGW-LABEL: test_nostack: 456 ; X32-MinGW-NOT: calll __morestack 457 458 ; X64-MinGW-LABEL: test_nostack: 459 ; X64-MinGW-NOT: callq __morestack 460 461 ; X64-FreeBSD-LABEL: test_nostack: 462 ; X64-FreeBSD-NOT: callq __morestack 463 } 464 465 attributes #0 = { "split-stack" } 466