Summary: | [4.2 Regression] VRP ICE in compare_names | ||
---|---|---|---|
Product: | gcc | Reporter: | kargls |
Component: | tree-optimization | Assignee: | Richard Biener <rguenth> |
Status: | RESOLVED FIXED | ||
Severity: | critical | CC: | dnovillo, fang, gcc-bugs, pinskia, rguenth |
Priority: | P3 | Keywords: | ice-on-valid-code |
Version: | 4.2.0 | ||
Target Milestone: | 4.2.0 | ||
Host: | Target: | ||
Build: | Known to work: | 4.1.2 | |
Known to fail: | 4.2.0 | Last reconfirmed: | 2006-10-13 10:38:52 |
Bug Depends on: | |||
Bug Blocks: | 31698 |
Description
kargls
2006-10-12 22:37:04 UTC
C testcase: void f(int *n, int *m) { int i; int ubound0; int ubound1; int stride2; int offset3; int size4; int j; int ubound5; int size6; int D919; __SIZE_TYPE__ D920; int D921; unsigned int D922; __SIZE_TYPE__ D923; unsigned int D924; ubound0 = *m; stride2 = ubound0; ubound1 = *n; size4 = stride2 * ubound1; D922 = size4 - 1; int (*abc)[D922]; abc = _gfortran_internal_malloc (size4 * 4); offset3 = ~stride2; ubound5 = *n; size6 = ubound5; D919 = size6 - 1; int (*xsd)[D919]; xsd = _gfortran_internal_malloc (size6 * 4); i = 1; if (i <= 2) { while (1) { { _Bool D918; j = 1; if (j <= 3) { while (1) { { _Bool D917; if (i != j) { if (__builtin_expect (ubound0 <= 0, 0)) { __builtin_abort (); } else { (void) 0; } if (__builtin_expect (ubound1 <= 0, 0)) { __builtin_abort (); } else { (void) 0; } (*abc)[stride2 + offset3 + 1] = 0; } else { { int D916; if (__builtin_expect (ubound0 <= 0, 0)) { __builtin_abort (); } else { (void) 0; } D916 = j; if (__builtin_expect (D916 <= 0, 0)) { __builtin_abort (); } else { (void) 0; } if (__builtin_expect (D916 > ubound1, 0)) { __builtin_abort (); } else { (void) 0; } if (__builtin_expect (ubound5 <= 0, 0)) { __builtin_abort (); } else { (void) 0; } (*abc)[D916 * stride2 + offset3 + 1] = (*xsd)[0]; } } D917 = j == 3; j = j + 1; if (D917) break; else (void) 0; } } } else { (void) 0; } // L4:; D918 = i == 2; i = i + 1; if (D918) break; else (void) 0; } } } else { (void) 0; } //L2:; _gfortran_internal_free ((void *) xsd); _gfortran_internal_free ((void *) abc); } here is a shorter testcase: void f(void) { int i, ubound1, j, ubound5; int (*abc)[3]; i = 1; while (1) { if (j <= 3) while (1) { _Bool D917; if (i != j) { if (__builtin_expect (ubound1 <= 0, 0)) __builtin_abort (); (*abc)[1] = 0; } else { int D916; D916 = j; if (__builtin_expect (D916 > ubound1, 0)) __builtin_abort (); if (__builtin_expect (ubound5 <= 0, 0)) __builtin_abort (); } j = j + 1; if (D917) break; } i = i + 1; } } Slightly less undefined, ICEs with -O -ftree-vrp -funswitch-loops: void f(_Bool D917, int j0, int ubound1, int ubound5) { int i, j = j0; int (*abc)[3]; i = 1; while (1) { if (j <= 3) while (1) { if (i != j) { if (ubound1 <= 0) return; (*abc)[1] = 0; } else { if (j > ubound1) return; if (ubound5 <= 0) return; } j = j + 1; if (D917) break; } i = i + 1; } } We end up comparing (GT_EXPR) i_92 with ubound1_111 which have the following value ranges and equivalences: i_92: [1, 3] EQUIVALENCES: { i_1 j_2 i_67 j_70 } (4 elements) i_1: ~[0, 0] EQUIVALENCES: { } (0 elements) j_2: VARYING i_67: [1, ubound1_8] EQUIVALENCES: { i_1 } (1 elements) j_70: [-INF, 3] EQUIVALENCES: { j_2 } (1 elements) ubound1_111: [-INF, 0] EQUIVALENCES: { ubound1_8 ubound1_112 } (2 elements) ubound1_8: VARYING ubound1_112: [i_67, +INF] EQUIVALENCES: { ubound1_8 } (1 elements) i_67 > ubound1_8 ([1, ubound1_8] > [ubound1_8, ubound1_8]) is false i_67 > ubound1_111 ([1, ubound1_8] > [-INF, 0]) is true i_92 > ubound1_111 ([1, 3] > [-INF, 0]) is true So we have a cross-equivalency set inconsistency. It looks like we would need to recurse down into symbolic ranges in fix_equivalence_set, which would be far too costly. So a conservative fix for 4.2 is to just not record symbolic equivalencies at all. I wonder if there is a better way to deal with these issues than fix_equivalence_set though. I have a patch to get rid of that beast completely. Subject: Bug number PR29446 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/2006-10/msg00698.html Subject: Bug 29446 Author: rguenth Date: Fri Oct 13 20:09:10 2006 New Revision: 117705 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117705 Log: 2006-10-13 Richard Guenther <rguenther@suse.de> PR tree-optimization/29446 * tree-vrp.c (fix_equivalence_set): Remove. (extract_range_from_assert): Do not call fix_equivalence_set. (debug_value_range): Print a newline. (compare_name_with_value): For equivalence sets with inconsistent value ranges conservatively bail out. (compare_names): Likewise. * gcc.dg/torture/pr29446.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/torture/pr29446.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-vrp.c Fixed. Subject: Bug 29446 Author: rguenth Date: Wed Apr 25 17:10:31 2007 New Revision: 124158 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=124158 Log: 2007-04-25 Richard Guenther <rguenther@suse.de> PR tree-optimization/31698 * g++.dg/other/pr31698.C: New testcase. Backport from mainline: 2006-10-13 Richard Guenther <rguenther@suse.de> PR tree-optimization/29446 * tree-vrp.c (fix_equivalence_set): Remove. (extract_range_from_assert): Do not call fix_equivalence_set. (debug_value_range): Print a newline. (compare_name_with_value): For equivalence sets with inconsistent value ranges conservatively bail out. (compare_names): Likewise. * gcc.dg/torture/pr29446.c: New testcase. Added: branches/gcc-4_1-branch/gcc/testsuite/g++.dg/other/pr31698.C branches/gcc-4_1-branch/gcc/testsuite/gcc.dg/torture/pr29446.c - copied unchanged from r117705, trunk/gcc/testsuite/gcc.dg/torture/pr29446.c Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/testsuite/ChangeLog branches/gcc-4_1-branch/gcc/tree-vrp.c |