------- Comment #1 from jakub at gcc dot gnu dot org 2008-11-24 09:01 ------- Smaller testcase: static inline int f1 (int si1, int si2) { return si2 == 0 ? si1 : si1 / si2; }
static inline unsigned long long f2 (unsigned long long ui1, unsigned long long ui2) { return ui1 % ui2; } unsigned char g; volatile unsigned int h; void f3 (void) { if (!((signed char) f1 (0, f2 (g, 2123)) - 1)) h; } int main (void) { f3 (); return 0; } The problem seems to be that RTL DCE pass removes umoddi3 call: (insn 8 6 34 2 u2.c:19 (set (mem:DI (plus:SI (reg/f:SI 7 sp) (const_int 8 [0x8])) [0 S8 A32]) (const_int 2123 [0x84b])) 88 {*movdi_2} (nil)) (insn 34 8 35 2 u2.c:19 (set (mem:SI (reg/f:SI 7 sp) [0 S4 A32]) (reg:SI 61 [ g ])) 47 {*movsi_1} (expr_list:REG_DEAD (reg:SI 61 [ g ]) (nil))) (insn 35 34 10 2 u2.c:19 (set (mem:SI (plus:SI (reg/f:SI 7 sp) (const_int 4 [0x4])) [0 S4 A32]) (const_int 0 [0x0])) 47 {*movsi_1} (nil)) (call_insn/u 10 35 0 2 u2.c:19 (set (reg:DI 0 ax) (call (mem:QI (symbol_ref:SI ("__umoddi3") [flags 0x41]) [0 S1 A8]) (const_int 16 [0x10]))) 902 {*call_value_0} (expr_list:REG_UNUSED (reg:SI 1 dx) (expr_list:REG_EH_REGION (const_int -1 [0xffffffffffffffff]) (nil))) (expr_list:REG_DEP_TRUE (use (mem:DI (reg/f:SI 7 sp) [0 S8 A8])) (expr_list:REG_DEP_TRUE (use (mem:DI (plus:SI (reg/f:SI 7 sp) (const_int 8 [0x8])) [0 S8 A8])) (nil)))) but doesn't remove the pushes of its arguments, and then ix86_compute_frame_layout doesn't allocate space for the outgoing arguments as the function is leaf. /* Add outgoing arguments area. Can be skipped if we eliminated all the function calls as dead code. Skipping is however impossible when function calls alloca. Alloca expander assumes that last crtl->outgoing_args_size of stack frame are unused. */ if (ACCUMULATE_OUTGOING_ARGS && (!current_function_is_leaf || cfun->calls_alloca || ix86_current_function_calls_tls_descriptor)) { offset += crtl->outgoing_args_size; frame->outgoing_arguments_size = crtl->outgoing_args_size; } else frame->outgoing_arguments_size = 0; I guess this was caused by the removal of REG_LIBCALL notes. -- jakub at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |steven at gcc dot gnu dot | |org Component|c |rtl-optimization Known to fail| |4.4.0 Known to work| |4.3.2 Summary|apparent improper segfault |[4.4 Regression] apparent |in compiler output |improper segfault in | |compiler output Target Milestone|--- |4.4.0 Version|unknown |4.4.0 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38245