[525] % gcctk -v Using built-in specs. COLLECT_GCC=gcctk COLLECT_LTO_WRAPPER=/local/suz-local/software/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/11.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-trunk/configure --disable-bootstrap --prefix=/local/suz-local/software/local/gcc-trunk --enable-languages=c,c++ --disable-werror --enable-multilib --with-system-zlib Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.0.0 20201118 (experimental) [master revision b03be74bad0:b7ec4b4b7a1:4b81528241ca682025d92558ff6aeec91dafdca8] (GCC) [526] % [526] % gcctk -O1 small.c; ./a.out [527] % [527] % gcctk -Os small.c [528] % ./a.out Illegal instruction [529] % [529] % cat small.c int a = 1, b, c = 4, d, e; int main() { int f = 2273363750; for (; b < 10; b++) { int g = f % (~0 && a) && g, h = 0, i = 0; if (c) h = f; if (h > -2021603546) e = d / i; f = h; } return 0; }
Started with r11-5111-g1e27e7a582a9b86bcf86f5c103cd947672746e97
The comments in that commit look incorrect btw, // if a & b >=0 , then a >= 0. should have been // if a % b >=0 , then a >= 0. (ditto the other one).
And I think the commit doesn't implement what Bruno wrote. In particular, it was b >= 0 && a % b > 0 implies a >= 0 b >= 0 && a % b < 0 implies a <= 0 while the patch implemented b >= 0 && a % b >= 0 implies a >= 0 b >= 0 && a % b < 0 implies a <= 0 Consider -4 % 4, b >= 0 and a % b == 0, which is >= 0, but a is < 0. So, another miscompiled testcase is: __attribute__((noipa)) void foo (int i) { if ((i % 7) >= 0) { if (i >= 0) __builtin_abort (); } } int main () { foo (-7); foo (-21); return 0; }
Created attachment 49585 [details] gcc11-pr97888.patch Untested fix.
Doh, yeah. Patch looks good.
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:71c9d2b088c9d409a1bd3b50523ac4623a5bf1b4 commit r11-5150-g71c9d2b088c9d409a1bd3b50523ac4623a5bf1b4 Author: Jakub Jelinek <jakub@redhat.com> Date: Wed Nov 18 22:13:06 2020 +0100 vrp: Fix operator_trunc_mod::op1_range [PR97888] As mentioned in the PR, in (x % y) >= 0 && y >= 0, we can't deduce x's range to be x >= 0, as e.g. -7 % 7 is 0. But we can deduce it from (x % y) > 0. The patch also fixes up the comments. 2020-11-18 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/91029 PR tree-optimization/97888 * range-op.cc (operator_trunc_mod::op1_range): Only set op1 range to >= 0 if lhs is > 0, rather than >= 0. Fix up comments. * gcc.dg/pr91029.c: Add comment with PR number. (f2): Use > 0 rather than >= 0. * gcc.c-torture/execute/pr97888-1.c: New test. * gcc.c-torture/execute/pr97888-2.c: New test.
Fixed.