This seems to be a recent regression. $ gcc-trunk -v Using built-in specs. COLLECT_GCC=gcc-trunk COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-source-trunk/configure --enable-languages=c,c++,lto --prefix=/usr/local/gcc-trunk --disable-bootstrap Thread model: posix gcc version 7.0.1 20170130 (experimental) [trunk revision 245020] (GCC) $ $ gcc-trunk -m32 -O2 small.c; ./a.out $ gcc-trunk -m64 -O3 small.c; ./a.out $ $ gcc-trunk -m32 -O3 small.c $ ./a.out Segmentation fault (core dumped) $ --------------------------------------------- int printf (const char *, ...); int a[6], b, c, d, e, f, g, h; static int i[][8] = { { 0 } }; void fn1 (int l) { c = (c & 5) ^ a[(c ^ l) & 5]; } void fn2 () { fn1 (e >> 5); fn1 (e >> 6 & 5); c = (c & 5) ^ a[(c ^ 5) & 5]; fn1 (e >> 2 & 5); fn1 (e & 5); fn1 (e >> 28 & 5); } void fn3 () { int k; for (; g < 4; g++) { while (d) { fn2 (); if (k) printf ("%d\n", k); } while (f) while (h++) k = i[300000000000000000][0]; while (b) while (1) d++; } } int main () { fn3 (); return 0; }
Confirmed, started with r239357.
Reducing the test-case bit more: $ int a = 0, c = 0; static int d[][8] = {}; int main () { int e; for (int b = 0; b < 4; b++) { __builtin_printf ("%d\n", b, e); while (a && c++) e = d[300000000000000000][0]; } return 0; } Problem is that we segfault here: │0x8048448 <main+13> push %ebx │0x8048449 <main+14> push %ecx │0x804844a <main+15> mov $0x0,%ebx │0x804844f <main+20> jmp 0x8048459 <main+30> │0x8048451 <main+22> add $0x1,%ebx │0x8048454 <main+25> cmp $0x4,%ebx │0x8048457 <main+28> je 0x804849f <main+100> │0x8048459 <main+30> sub $0x4,%esp >│0x804845c <main+33> pushl 0x1bc48534 which is I guess d[300000000000000000][0], which is a dead-code that is placed before the printf call first time in 273r.ira: ... (insn 8 7 9 3 (set (mem:SI (pre_dec:SI (reg/f:SI 7 sp)) [1 S4 A32]) (mem/u:SI (const:SI (plus:SI (symbol_ref:SI ("d") [flags 0x2] <var_decl 0x7fc764859f30 d>) (const_int 331350016 [0x13c00000]))) [1 d+331350016 S4 A32])) "tc.c":9 58 {*pushsi2} (expr_list:REG_ARGS_SIZE (const_int 8 [0x8]) (nil))) (insn 9 8 10 3 (set (mem:SI (pre_dec:SI (reg/f:SI 7 sp)) [1 S4 A32]) (reg/v:SI 88 [ b ])) "tc.c":9 58 {*pushsi2} (expr_list:REG_ARGS_SIZE (const_int 12 [0xc]) (nil))) (insn 10 9 11 3 (set (mem/f:SI (pre_dec:SI (reg/f:SI 7 sp)) [2 S4 A32]) (symbol_ref/f:SI ("*.LC0") [flags 0x2] <var_decl 0x7fc76322eab0 *.LC0>)) "tc.c":9 58 {*pushsi2} (expr_list:REG_ARGS_SIZE (const_int 16 [0x10]) (nil))) (call_insn 11 10 12 3 (set (reg:SI 0 ax) (call (mem:QI (symbol_ref:SI ("printf") [flags 0x41] <function_decl 0x7fc76318be00 __builtin_printf>) [0 __builtin_printf S1 A8]) (const_int 16 [0x10]))) "tc.c":9 663 {*call_value} (expr_list:REG_UNUSED (reg:SI 0 ax) (nil)) (nil)) That points to a different commit, I'll bisect that.
Mine (looks like a latent issue though).
My small test-case started to segfault with r235660.
Unassigning then.
The testcase in comment #2 fails with x86 -m32 -Os even after fixing the ira failure, due to lra doing "Changing pseudo 89 in operand 1 of insn 9 on equiv [const(`d'+0x13c00000)]" This puts the load of d[300...0][0] before the printf, just like the ira bug. The -Os failure is a regression from gcc-3.4
Author: law Date: Thu Feb 16 22:56:51 2017 New Revision: 245521 URL: https://gcc.gnu.org/viewcvs?rev=245521&root=gcc&view=rev Log: 2017-02-16 Alan Modra <amodra@gmail.com> PR rtl-optimization/79286 * ira.c (def_dominates_uses): New function. (update_equiv_regs): Don't create an equivalence for insns that may trap where the register def does not dominate the use. * gcc.c-torture/execute/pr79286.c: New. Added: trunk/gcc/testsuite/gcc.c-torture/execute/pr79286.c Modified: trunk/gcc/ChangeLog trunk/gcc/ira.c trunk/gcc/testsuite/ChangeLog
Fixed by Alan's patch on the trunk.
See https://gcc.gnu.org/ml/gcc-patches/2017-02/msg01172.html.
Author: law Date: Fri Feb 24 15:36:10 2017 New Revision: 245714 URL: https://gcc.gnu.org/viewcvs?rev=245714&root=gcc&view=rev Log: PR rtl-optimizatoin/79286 * ira.c (update_equiv_regs): Drop may_trap_p exception to dominance test. Modified: trunk/gcc/ChangeLog trunk/gcc/ira.c
Darwin issues should be fixed now too.
Hi Jeff, it looks like it is possible that may_trap_p returns always wrong information if -m32 -fPIC is used. What do you think about this? Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c (revision 245714) +++ gcc/rtlanal.c (working copy) @@ -645,8 +645,23 @@ case PLUS: /* An address is assumed not to trap if: - it is the pic register plus a constant. */ - if (XEXP (x, 0) == pic_offset_table_rtx && CONSTANT_P (XEXP (x, 1))) - return 0; + if (XEXP (x, 0) == pic_offset_table_rtx + && GET_CODE (XEXP (x, 1)) == CONST) + { + x = XEXP (XEXP (x, 1), 0); + if (GET_CODE (x) == UNSPEC + && GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF) + return rtx_addr_can_trap_p_1(XVECEXP (x, 0, 0), + offset, size, mode, unaligned_mems); + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == UNSPEC + && GET_CODE (XVECEXP (XEXP (x, 0), 0, 0)) == SYMBOL_REF + && CONST_INT_P (XEXP (x, 1))) + return rtx_addr_can_trap_p_1(XVECEXP (XEXP (x, 0), 0, 0), + offset + INTVAL (XEXP (x, 1)), + size, mode, unaligned_mems); + return 1; + } /* - or it is an address that can't trap plus a constant integer. */ if (CONST_INT_P (XEXP (x, 1))
I think we're done here.