It should be a very recent regression. $ gcc-trunk -v Using built-in specs. COLLECT_GCC=gcc-trunk COLLECT_LTO_WRAPPER=/home/absozero/trunk/root-gcc/libexec/gcc/x86_64-pc-linux-gnu/9.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc/configure --prefix=/home/absozero/trunk/root-gcc --enable-languages=c,c++ --disable-werror --enable-multilib Thread model: posix gcc version 9.0.0 20181007 (experimental) [trunk revision 264906] (GCC) $ gcc-trunk abc.c ; ./a.out -37 $ gcc-trunk -O3 abc.c ; ./a.out 219 $ cat abc.c int printf(const char *, ...); int a; long b, f; char c, g; short d = 219; int e[7]; int main() { for (; c <= 6; c++) { g = d < 0 ? d : d >> a; f = g + b; e[c] = f; } printf("%d\n", e[1]); }
Confirmed. Caused by loop vectorization (some pattern recog stuff appearantly).
Started with r262333.
'b' is never assigned a value, so surely it's undefined -------- Original message -------- From: helloqirun at gmail dot com <gcc-bugzilla@gcc.gnu.org> Date: 08/10/2018 04:51 (GMT+00:00) To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/87546] New: Gcc miscompiles at -O3 on valid code https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87546 Bug ID: 87546 Summary: Gcc miscompiles at -O3 on valid code Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: helloqirun at gmail dot com Target Milestone: --- It should be a very recent regression. $ gcc-trunk -v Using built-in specs. COLLECT_GCC=gcc-trunk COLLECT_LTO_WRAPPER=/home/absozero/trunk/root-gcc/libexec/gcc/x86_64-pc-linux-gnu/9.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc/configure --prefix=/home/absozero/trunk/root-gcc --enable-languages=c,c++ --disable-werror --enable-multilib Thread model: posix gcc version 9.0.0 20181007 (experimental) [trunk revision 264906] (GCC) $ gcc-trunk abc.c ; ./a.out -37 $ gcc-trunk -O3 abc.c ; ./a.out 219 $ cat abc.c int printf(const char *, ...); int a; long b, f; char c, g; short d = 219; int e[7]; int main() { for (; c <= 6; c++) { g = d < 0 ? d : d >> a; f = g + b; e[c] = f; } printf("%d\n", e[1]); }
(In reply to graham.stott77 from comment #3) > 'b' is never assigned a value, so surely it's undefined No. b has static storage duration and therefore it is initialized to zero.
So, I think the bug is in vect_look_through_possible_promotion, which doesn't do what it claims to do is that what it returns can be cast to unprom->type and then promoted to final precision and that it is the same as the original cast sequence. Here we have: _39 = (long int) iftmp.0_19; in the loop and _4 = _2 >> a.4_3; iftmp.0_19 = (signed char) _4; before the loop, with int _4; signed char iftmp.0_19; long int _39; and we return _4 and unprom is { _4, int, vect_external_def, NULL } (NULL caster because this is already outside of the loop). (long int) (int) _4 is not equivalent to (long int) (signed char) (int) _4 though, so we should have returned iftmp.0_19 in this case and unprom { iftmp.0_19, signed char, vect_external_def, caster }.
Created attachment 45026 [details] gcc9-pr87546.patch Untested fix.
Author: jakub Date: Sat Nov 17 15:10:48 2018 New Revision: 266237 URL: https://gcc.gnu.org/viewcvs?rev=266237&root=gcc&view=rev Log: PR tree-optimization/87546 * tree-vect-patterns.c (vect_look_through_possible_promotion): Add min_precision variable, initially set it to orig_precision, only does something if op_type's precision is <= min_precision and update min_precision whenever calling set_op. * gcc.dg/vect/O3-pr87546.c: New test. Added: trunk/gcc/testsuite/gcc.dg/vect/O3-pr87546.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-vect-patterns.c
Fixed.