------- Comment #8 from rguenth at gcc dot gnu dot org 2010-03-27 16:38 ------- Just to clarify, the issue is that
(insn 6 5 7 2 t.i:2 (set (reg:DF 21 xmm0) (float_extend:DF (mem/u/c/i:SF (symbol_ref/u:SI ("*.LC0") [flags 0x2]) [0 S4 A32]))) 99 {*extendsfdf2_i387} (expr_list:REG_EQUAL (const_double:DF -2147483648 [0x80000000] 1.0e+0 [0x0.8p+1]) (nil))) with (define_insn "*extendsfdf2_i387" [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] "TARGET_80387" "* return output_387_reg_move (insn, operands);" [(set_attr "type" "fmov") (set_attr "mode" "SF,XF")]) requires a reload for the x87 register to xmm0 move. The (define_insn "*extendsfdf2_sse" [(set (match_operand:DF 0 "nonimmediate_operand" "=x") (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))] "TARGET_SSE2 && TARGET_SSE_MATH" "%vcvtss2sd\t{%1, %d0|%d0, %1}" [(set_attr "type" "ssecvt") (set_attr "prefix" "maybe_vex") (set_attr "mode" "DF")]) alternative is not enabled, both because just -msse is supplied and SSE math is not enabled. But I fail to see why we can't go through unaligned memory if the user asks us to - which puts the finger at the assert that triggers (and maybe reload if it can not properly deal with less aligned stack slots). Testcase that doesn't need -msseregparm: extern void __attribute__((sseregparm)) bar(double); void foo() { bar(1.0); } commenting the assert yields odd foo: pushl %ebp movl %esp, %ebp subl $8, %esp fld1 fstpl -8(%ebp) movlps -8(%ebp), %xmm0 call bar leave ret obviously w/o -msse2 there's no movsd, thus the odd code. And the handed out secondary memory has correct alignment: insn 6 5 11 2 t.i:2 (set (reg:DF 8 st) (float_extend:DF (mem/u/c/i:SF (symbol_ref/u:SI ("*.LC0") [flags 0x2]) [0 S4 A32]))) 99 {*extendsfdf2_i387} (expr_list:REG_EQUAL (const_double:DF -2147483648 [0x80000000] 1.0e+0 [0x0.8p+1]) (nil))) (insn 11 6 12 2 t.i:2 (set (mem/c:DF (plus:SI (reg/f:SI 6 bp) (const_int -8 [0xfffffff8])) [0 S8 A32]) (reg:DF 8 st)) 74 {*movdf_nointeger} (nil)) (insn 12 11 7 2 t.i:2 (set (reg:DF 21 xmm0) (mem/c:DF (plus:SI (reg/f:SI 6 bp) (const_int -8 [0xfffffff8])) [0 S8 A32])) 74 {*movdf_nointeger} (nil)) (call_insn 7 12 10 2 t.i:2 (call (mem:QI (symbol_ref:SI ("bar") [flags 0x41] <function_decl 0xb77a4c80 bar>) [0 S1 A8]) (const_int 0 [0x0])) 484 {*call_0} (nil) (expr_list:REG_DEP_TRUE (use (reg:DF 21 xmm0)) (nil))) so why are we using assign_stack_local here and not assign_stack_local_1 (..., true)? Here, at #3 0x0846d729 in get_secondary_mem (x=0xb77a96f0, mode=DFmode, opnum=0, type=RELOAD_FOR_OUTPUT) at /home/richard/src/trunk/gcc/reload.c:608 608 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0); (gdb) l 603 { 604 #ifdef SECONDARY_MEMORY_NEEDED_RTX 605 secondary_memlocs[(int) mode] = SECONDARY_MEMORY_NEEDED_RTX (mode); 606 #else 607 secondary_memlocs[(int) mode] 608 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0); 609 #endif 610 } -- rguenth at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43546