On ia64, gcc produces bad code for stack frames greater than 2 GB when no optimization is used. It works fine with -O1 and above. This results in the application core dumping from a SEGV. For example: $ cat test.c int test() { char buf[4000000000]; bzero(buf, sizeof(buf)); } $ gcc -v Reading specs from /usr/local/lib/gcc-lib/ia64-unknown-linux-gnu/3.3/specs Configured with: ./configure Thread model: posix gcc version 3.3 $ gcc -c test.c $ objdump -d test.o test.o: file format elf64-ia64-little Disassembly of section .text: 0000000000000000 <test>: 0: 0c 08 19 08 80 05 [MFI] alloc r33=ar.pfs,6,4,0 6: 00 00 00 02 00 40 nop.f 0x0 c: 04 60 00 84 mov r34=r12 10: 05 00 00 00 01 80 [MLX] nop.m 0x0 16: 11 ff ff ff 7f 20 movl r17=0xffffffff1194d800;; 1c: 02 80 c2 6e 20: 00 60 30 22 00 20 [MII] add r12=r12,r17 26: 30 02 04 00 42 00 mov r35=r1 2c: 04 00 c4 00 mov r32=b0 30: 05 00 00 00 01 80 [MLX] nop.m 0x0 36: 11 00 00 00 00 80 movl r36=0x1194d810;; ^^^^^^^^^^^^^^^^^^^^^ should be 0xffffffff1194d810 3c: 04 81 c2 66 40: 04 20 91 44 00 60 [MLX] add r36=r36,r34 46: ee 00 00 00 00 a0 movl r37=0xee6b2800 4c: 04 70 41 61 50: 1c 00 00 00 01 00 [MFB] nop.m 0x0 56: 00 00 00 02 00 00 nop.f 0x0 5c: 08 00 00 50 br.call.sptk.many b0=50 <test+0x50> 60: 02 08 00 46 00 21 [MII] mov r1=r35 66: 80 00 38 00 42 00 mov r8=r14;; 6c: 10 02 aa 00 mov.i ar.pfs=r33 70: 00 00 00 00 01 00 [MII] nop.m 0x0 76: 00 00 05 80 03 80 mov b0=r32 7c: 01 10 01 84 mov r12=r34 80: 1d 00 00 00 01 00 [MFB] nop.m 0x0 86: 00 00 00 02 00 80 nop.f 0x0 8c: 08 00 84 00 br.ret.sptk.many b0;; Note the movl at offset 36 should be 0xffffffff1194d810 instead of 0x1194d810. As mentioned before, this only occurs with no optimization, i.e. -O1 and above work fine. It also occurs with all previous versions tested - 3.2.x, 2.96, etc. Tested on Itanium & Itanium2 boxes running Red Hat Advanced Server 2.1.
I can confirm this on the mainline (20030705): .align 16 .global test# .proc test# test: .prologue 14, 32 .save ar.pfs, r33 alloc r33 = ar.pfs, 0, 4, 2, 0 .vframe r34 mov r34 = r12 movl r17 = -4000000000 ;; add r12 = r12, r17 mov r35 = r1 .save rp, r32 mov r32 = b0 .body movl r36 = 294967312 <----- here ;; add r36 = r36, r34 movl r37 = 4000000000 br.call.sptk.many b0 = bzero# mov r1 = r35 mov r8 = r14 ;; mov ar.pfs = r33 mov b0 = r32 .restore sp mov r12 = r34 br.ret.sptk.many b0 ;; .endp test#
Looks like something is an int when it should be a HOST_WIDE_INT but I could not find it.
There are loads of places in the ia64 backend where HOST_WIDE_INT should be instead of int but I did not place which one would fix this bug.
I just tested this and found I could reproduce it with 3.2.3 and 3.3, but the 3.4 and top of tree (pre-4.0) versions look OK. I.e. they produce the proper negative number. The test case still fails but I believe this is because I am running into the maximum stack size limit on the kernel.
Resolving as fixed since 3.4 and ToT both look OK. It is still broken on the 3.3 branch.