The following function should just "return 1": int f(int i) { int i1 = i -2; if (i1 > i) return 0; return 1; } We miss this on the tree level, I found this while look into the following fortran code: SUBROUTINE d ( a, b,n) IMPLICIT NONE INTEGER :: n REAL,DIMENSION(n) :: a REAL,DIMENSION(n) :: b b(n-2:n) = sqrt(a(n-2:n)) END SUBROUTINE d In final_cleanup, we have: D.679 = *n; S.2 = D.679 - 2; if (D.679 < S.2) goto L.1; else goto <L7>;
Reduced testcase showing fold does not do it: int f(int i) { return (i - 2) > i; }
This is not caught untill RTL combine.
Note this is only true with -fno-wrapv (which is default for C and C++ and I think Fortran too but not Java).
Confirmed, the code which does this on the RTL level is in simplify_const_relational_operation.
Created attachment 8654 [details] Fold stuff
Created attachment 8655 [details] tests
Created attachment 8656 [details] more tests
Created attachment 8657 [details] tests galour
Created attachment 8658 [details] reverse tests
Created attachment 8659 [details] yup, more
Created attachment 8660 [details] I only have 6 files so far
Created attachment 8673 [details] Attempt 2
Subject: Bug 20922 CVSROOT: /cvs/gcc Module name: gcc Changes by: phython@gcc.gnu.org 2005-04-18 15:18:22 Modified files: gcc : ChangeLog fold-const.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg: pr20922-1.c pr20922-2.c pr20922-3.c pr20922-4.c pr20922-5.c pr20922-6.c Log message: 2005-04-18 James A. Morrison <phython@gcc.gnu.org> PR tree-optimization/20922 * fold-const.c (fold_binary): Fold X - c > X and X + c < X to false. Fold X + c >= X and fold X - c <= X to true. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.8345&r2=2.8346 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fold-const.c.diff?cvsroot=gcc&r1=1.562&r2=1.563 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5364&r2=1.5365 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/pr20922-1.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/pr20922-2.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/pr20922-3.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/pr20922-4.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/pr20922-5.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/pr20922-6.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
Fixed in the last commit.
Is this optimization really legal in C/C++? Could some language lawyer look at this (and check the output when compiling with -O3): #include <limits.h> int f1(int i) { return (i - 2) > i; } int f2(int i) { return (i + 2) > i; } int g1(void) { return f1(INT_MIN); } int g2(void) { return f2(INT_MAX); }
(In reply to comment #15) > Is this optimization really legal in C/C++? Could some language lawyer look at > this (and check the output when compiling with -O3): Overflow/Underflow of signed operands in C/C++ is undefined, now in Java it is not.
Subject: Re: missed always false conditional On 25 Apr 2005 00:39:23 -0000, markus at oberhumer dot com <gcc-bugzilla@gcc.gnu.org> wrote: > > > -- > What |Removed |Added > ---------------------------------------------------------------------------- > CC| |markus at oberhumer dot com > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20922 The overflow semantics are undefined for signed types in C/C++. Try with -ftrapv or -fwrapv if you need defined semantics for C/C++.
Ah, many thanks for the clarification. Still it's somewhat confusing that f1() and g1() don't agree after inlining, but "undefined" probably means exactly that...