Gcc generates different 32bit assembly codes in 32bit and 64bit hosts: 1. On 64bit host, [hjl@gnu-26 stage1-gcc]$ cat x.i _Decimal128 test (void) { return 1234123412341234.123412341234dl; } [hjl@gnu-26 stage1-gcc]$ ./xgcc -B./ -msse -S -m32 -march=i386 -mtune=generic x.i [hjl@gnu-26 stage1-gcc]$ cat x.s .file "x.i" .text .globl test .type test, @function test: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movaps .LC0, %xmm0 movaps %xmm0, (%eax) popl %ebp ret $4 .size test, .-test .section .rodata .align 16 .LC0: .long 84673010 .long 1025550150 .long 66901964 .long 807927808 .ident "GCC: (GNU) 4.4.0 20080304 (experimental) [trunk revision 132852]" .section .note.GNU-stack,"",@progbits [hjl@gnu-26 stage1-gcc]$ 2. On 32bit host, [hjl@gnu-9 stage1-gcc]$ cat x.i _Decimal128 test (void) { return 1234123412341234.123412341234dl; } [hjl@gnu-9 stage1-gcc]$ ./xgcc -B./ -msse -S -m32 -march=i386 -mtune=generic x.i [hjl@gnu-9 stage1-gcc]$ cat x.s .file "x.i" .text .globl test .type test, @function test: pushl %ebp movl %esp, %ebp subl $24, %esp movl 8(%ebp), %eax movaps .LC0, %xmm0 movaps %xmm0, -24(%ebp) movaps -24(%ebp), %xmm0 movaps %xmm0, (%eax) leave ret $4 .size test, .-test .section .rodata .align 16 .LC0: .long 84673010 .long 1025550150 .long 66901964 .long 807927808 .ident "GCC: (GNU) 4.4.0 20080304 (experimental) [trunk revision 132852]" .section .note.GNU-stack,"",@progbits [hjl@gnu-9 stage1-gcc]$ Where does "subl $24, %esp" on 32bit host come from?
The difference comes from tree_expand_cfg pass: [hjl@gnu-9 stage1-gcc]$ diff -up 32/x.i.132r.expand 64 --- 32/x.i.132r.expand 2008-03-04 20:25:21.000000000 -0800 +++ 64/x.i.132r.expand 2008-03-04 20:25:12.000000000 -0800 @@ -5,20 +5,18 @@ ;; Generating RTL for tree basic block 2 ;; <retval> = 1234123412341234.123412341234 -(insn 6 5 7 x.i:3 (set (subreg:TI (reg:TD 59) 0) - (mem/u/c:TI (symbol_ref/u:SI ("*.LC0") [flags 0x2]) [0 S16 A128])) -1 (nil)) - -(insn 7 6 8 x.i:3 (set (reg:TI 60) - (subreg:TI (reg:TD 59) 0)) -1 (nil)) +(insn 6 5 7 x.i:3 (set (reg:TI 59) + (mem/u/c/i:TI (symbol_ref/u:SI ("*.LC0") [flags 0x2]) [0 S16 A128])) -1 (expr_list:REG_EQUAL (const_double 4404704354742567410 [0x3d20a746050c01f2] 3470023512955869132 [0x3028000003fcd7cc] 0 [0x0] 0 [0x0]) + (nil))) -(insn 8 7 0 x.i:3 (set (mem/c/i:TI (reg/f:SI 58 [ D.1355 ]) [0 <result>+0 S16 A128]) - (reg:TI 60)) -1 (nil)) +(insn 7 6 0 x.i:3 (set (mem/c/i:TI (reg/f:SI 58 [ D.1370 ]) [0 <result>+0 S16 A128]) + (reg:TI 59)) -1 (nil)) ;; return <retval>
This is a HWI issue. I don't know how many times I tell people that x86 should default to 64bit HWI if it uses TImode.
Indeed. Maybe we should finally change the default.
Different code for the same target on different hosts is a valid bug, not INVALID. If a target works with more than one HOST_WIDE_INT setting, the choice should not affect the code generated; this is separate from the question of whether x86 targets should allow 32-bit HOST_WIDE_INT.
32bit HWI cannot represent 128bit constants. If you are lucky and it works as far as creating code you should not be surprised that some constants might be forced to memory. The only chance to generate the same code in this context is to pessimize code generation for 64bit HWI. We are not going to do that.
Then we should fix this bug by requiring 64-bit HOST_WIDE_INT for x86 targets rather than by declaring it will never be fixed. It can be closed when we've switched to 64-bit HOST_WIDE_INT (or as a duplicate if we already have a bug open for the issue). I don't recall any disagreement to the stated importance of generating the same code independent of host. http://gcc.gnu.org/ml/gcc-patches/2007-08/msg01598.html "I do think that generating the same code, independent of host system, is a very important property of GCC's design, just like generating the same code independent of whether or not we're compiling with -g." http://gcc.gnu.org/ml/gcc-patches/2007-08/msg01789.html "I've always thought these principles were meant to be sacrosanct"
*** Bug 39663 has been marked as a duplicate of this bug. ***
(In reply to comment #6) > Then we should fix this bug by requiring 64-bit HOST_WIDE_INT for x86 targets This is just the special case of GCC generating different code for the same target from different *hosts*; you'd have to require the same HOST_WIDE_INT for *all* hosts. Point: not a good *general* solution.
(In reply to comment #5) > 32bit HWI cannot represent 128bit constants. If you are lucky and it works as > far as creating code you should not be surprised that some constants might > be forced to memory. The only chance to generate the same code in this context > is to pessimize code generation for 64bit HWI. We are not going to do that. Yeah.