Bug 32500 - [4.2 Regression] Loop optimization limits range to size of array used inside loop
Summary: [4.2 Regression] Loop optimization limits range to size of array used inside ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.2.0
: P1 normal
Target Milestone: 4.2.1
Assignee: Richard Biener
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2007-06-25 15:35 UTC by Ed Schouten
Modified: 2007-07-06 13:14 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.3.0 4.1.2
Known to fail: 4.2.0
Last reconfirmed: 2007-07-04 10:16:51


Attachments
C source code which triggers the bug (222 bytes, text/plain)
2007-06-25 15:35 UTC, Ed Schouten
Details
GCC intermediate code (1.93 KB, text/plain)
2007-06-25 15:36 UTC, Ed Schouten
Details
Generated assembly code (541 bytes, text/plain)
2007-06-25 15:36 UTC, Ed Schouten
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Schouten 2007-06-25 15:35:16 UTC
Hello,

On the FreeBSD -CURRENT mailing lists a user of the upcoming FreeBSD release discovered a bug in the GCC that is shipped with the base system (4.2.0 20070514). This bug causes the amount of iterations in a loop to be limited to the range of an array used in a single part of the loop. When the size of the loop is increased (in the attached example, to 6 or higher) the problem disappears.

The issue is solved when compiling the application with -O1 or lower.
Comment 1 Ed Schouten 2007-06-25 15:35:49 UTC
Created attachment 13783 [details]
C source code which triggers the bug
Comment 2 Ed Schouten 2007-06-25 15:36:22 UTC
Created attachment 13784 [details]
GCC intermediate code
Comment 3 Ed Schouten 2007-06-25 15:36:40 UTC
Created attachment 13785 [details]
Generated assembly code
Comment 4 Andrew Pinski 2007-06-25 15:45:15 UTC
i.10_10: [5, 12]
  D.2123_11 = i.10_10 - 7;
D.2123_11: [0fffffffa, +INF] 

I think this might have been already fixed.
Comment 5 Andrew Pinski 2007-06-25 15:46:22 UTC
This works on the trunk.
Comment 6 Ed Schouten 2007-06-25 15:50:28 UTC
Thanks for confirming this. Will the fix in question be part of 4.2.1 as well?
Comment 7 Andrey Chernov 2007-06-25 16:08:53 UTC
Still not works with
gcc version 4.2.1 20070614 prerelease [FreeBSD]
try
cc -O2 foo.c; ./a.out
and 
cc -O foo.c; ./a.out
Comment 8 Ed Schouten 2007-06-25 16:52:17 UTC
(In reply to comment #0)
> When the size of the loop is increased (in the attached example, to 6 or
> higher) the problem disappears.

This should read:

> When the size of the array is increased (in the attached example, to 6 or
> higher) the problem disappears.
Comment 9 davids 2007-06-26 03:42:25 UTC
This should be marked as a 4.2.0 regression.
Comment 10 Richard Biener 2007-06-26 10:45:47 UTC
Confirmed.  This is a VRP or SCEV bug.
Comment 11 Ed Schouten 2007-06-26 11:26:47 UTC
It seems to be solved when using -fno-tree-vrp.
Comment 12 Richard Biener 2007-07-04 10:16:51 UTC
This is SCEV.  From

<L2>:;
  i_7 = ASSERT_EXPR <i_20, i_20 > 4>;
  i.10_10 = (unsigned int) i_7;
  D.2489_11 = i.10_10 - 7;
  if (D.2489_11 <= 2) goto <L3>; else goto <L4>;

we have

Found new range for i.10_10: [5, 12]


Visiting statement:
D.2489_11 = i.10_10 - 7;

(analyze_scalar_evolution
  (loop_nb = 1)
  (scalar = D.2489_11)
(get_scalar_evolution
  (scalar = D.2489_11)
  (scalar_evolution = {4294967290, +, 1}_1))
(set_scalar_evolution 
  (scalar = D.2489_11)
  (scalar_evolution = {4294967290, +, 1}_1))
) 
(instantiate_parameters
  (loop_nb = 1)
  (chrec = {4294967290, +, 1}_1)
  (res = {4294967290, +, 1}_1))
Found new range for D.2489_11: [4294967290, +INF]

which is wrong.  The new range should be ~[5, 4294967290].

scev_probably_wraps_p() returns false for the above chrec because for
the loop in question estimated_nb_iterations is 4(!) which is derived
from infer_loop_bounds_from_undefined.  On the trunk this is fixed
by rewriting number of iterations analysis.  On the 4.2 branch we
can fix this conservatively by

Index: tree-ssa-loop-niter.c
===================================================================
--- tree-ssa-loop-niter.c       (revision 126260)
+++ tree-ssa-loop-niter.c       (working copy)
@@ -1747,6 +1747,12 @@ infer_loop_bounds_from_undefined (struct
     {
       bb = bbs[i];
 
+      /* If BB is not executed in each iteration of the loop, we cannot
+        use the operations in it to infer reliable upper bound on the
+        # of iterations of the loop.  */
+      if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
+       continue;
+
       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
         {
          tree stmt = bsi_stmt (bsi);

I'm going to test this.
Comment 13 Ed Schouten 2007-07-04 12:06:14 UTC
Hello Richard,

I can confirm that the patch fixes this regression. I just installed a patch compiler on my FreeBSD box and I get a proper binary, even when I build it with '-O2 -ftree-vrp' (just to be sure). Thanks!

Any chance this patch will make it into 4.2.1?
Comment 14 Richard Biener 2007-07-04 12:38:37 UTC
Subject: Bug 32500

Author: rguenth
Date: Wed Jul  4 12:38:23 2007
New Revision: 126315

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=126315
Log:
2007-07-04  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/32500
	* tree-ssa-loop-niter.c (infer_loop_bounds_from_undefined):
	Only use basic blocks that are always executed to infer loop bounds.

	* gcc.c-torture/execute/pr32500.c: New testcase.

Added:
    branches/gcc-4_2-branch/gcc/testsuite/gcc.c-torture/execute/pr32500.c
Modified:
    branches/gcc-4_2-branch/gcc/ChangeLog
    branches/gcc-4_2-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_2-branch/gcc/tree-ssa-loop-niter.c

Comment 15 Richard Biener 2007-07-04 12:39:52 UTC
Subject: Bug 32500

Author: rguenth
Date: Wed Jul  4 12:39:42 2007
New Revision: 126316

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=126316
Log:
2007-07-04  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/32500
	* gcc.c-torture/execute/pr32500.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/pr32500.c
Modified:
    trunk/gcc/testsuite/ChangeLog

Comment 16 Richard Biener 2007-07-04 12:40:19 UTC
Fixed.
Comment 17 Ed Schouten 2007-07-04 17:35:40 UTC
Sorry if I'm being a nitpick...

The committed testcase contains a small error; it has an off-by-one bug that causes a small buffer overflow.

The line:

      foo(numbers[i]);

should be replaced with:

      foo(numbers[i - 1]);

It shouldn't cause any real problems, because it's just a testcase, but maybe some quite intelligent new optimizer might trip on that.
Comment 18 patchapp@dberlin.org 2007-10-30 07:25:21 UTC
Subject: Bug number PR tree-optimization/32500

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-10/msg01790.html
Comment 19 Volker Reichelt 2007-10-30 20:29:33 UTC
Subject: Bug 32500

Author: reichelt
Date: Tue Oct 30 20:29:22 2007
New Revision: 129780

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129780
Log:
	PR tree-optimization/32500
	* gcc.c-torture/execute/pr32500.c: Fix buffer overflow in testcase.

Modified:
    branches/gcc-4_2-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_2-branch/gcc/testsuite/gcc.c-torture/execute/pr32500.c

Comment 20 Volker Reichelt 2007-10-30 20:30:57 UTC
Subject: Bug 32500

Author: reichelt
Date: Tue Oct 30 20:30:47 2007
New Revision: 129781

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129781
Log:
	PR tree-optimization/32500
	* gcc.c-torture/execute/pr32500.c: Fix buffer overflow in testcase.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.c-torture/execute/pr32500.c