[PATCH] Fix PR70288
Richard Biener
rguenther@suse.de
Fri Mar 18 11:41:00 GMT 2016
The following fixes excessive compile-time and memory-usage needed to
build the testcases which is caused by severe mis-calculation of
size-after-unrolling because it simply assumes that conditionals
with is_gimple_min_invariant ops can be folded to a constant.
This is not always true, like for
int a[1], b[1];
if (a < b)
...
which causes the testcase to explode. The easiest fix is to look
for a change in constness due to peeling rather than only
constness.
Of course in the end we want to fold these (and comparing
&a[i] < &b[i] will run into the issue even w/o the fix). But it
is not clear to me to what we should simplify the compare - replacing
it with __builtin_trap () might be best I suppose but I'm sure
it will break things out in the wild in interesting ways. Not
optimizing is a better choice here IMHO.
Bootstrap & regtest running on x86_64-unknown-linux-gnu.
Richard.
2016-03-18 Richard Biener <rguenther@suse.de>
PR tree-optimization/70288
* tree-ssa-loop-ivcanon.c (tree_estimate_loop_size): Make sure
we do not estimate unsimplified all-constant conditionals or
switches as optimized away.
* gcc.dg/torture/pr70288-1.c: New testcase.
* gcc.dg/torture/pr70288-2.c: Likewise.
Index: gcc/tree-ssa-loop-ivcanon.c
===================================================================
*** gcc/tree-ssa-loop-ivcanon.c (revision 234320)
--- gcc/tree-ssa-loop-ivcanon.c (working copy)
*************** tree_estimate_loop_size (struct loop *lo
*** 298,308 ****
/* Conditionals. */
else if ((gimple_code (stmt) == GIMPLE_COND
&& constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
! && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop))
|| (gimple_code (stmt) == GIMPLE_SWITCH
&& constant_after_peeling (gimple_switch_index (
as_a <gswitch *> (stmt)),
! stmt, loop)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Constant conditional.\n");
--- 298,314 ----
/* Conditionals. */
else if ((gimple_code (stmt) == GIMPLE_COND
&& constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
! && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop)
! /* We don't simplify all constant compares so make sure
! they are not both constant already. See PR70288. */
! && (! is_gimple_min_invariant (gimple_cond_lhs (stmt))
! || ! is_gimple_min_invariant (gimple_cond_rhs (stmt))))
|| (gimple_code (stmt) == GIMPLE_SWITCH
&& constant_after_peeling (gimple_switch_index (
as_a <gswitch *> (stmt)),
! stmt, loop)
! && ! is_gimple_min_invariant (gimple_switch_index (
! as_a <gswitch *> (stmt)))))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Constant conditional.\n");
Index: gcc/testsuite/gcc.dg/torture/pr70288-1.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr70288-1.c (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr70288-1.c (working copy)
***************
*** 0 ****
--- 1,36 ----
+ /* { dg-do compile } */
+ /* { dg-require-effective-target int32plus } */
+
+ int main()
+ {
+ int var6 = -1267827473;
+ do {
+ ++var6;
+ double s1_115[4], s2_108[4];
+ int var8 = -161498264;
+ do {
+ ++var8;
+ int var12 = 1260960076;
+ for (; var12 <= 1260960080; ++var12) {
+ int var13 = 1960990937;
+ do {
+ ++var13;
+ int var14 = 2128638723;
+ for (; var14 <= 2128638728; ++var14) {
+ int var22 = -1141190839;
+ do {
+ ++var22;
+ if (s2_108 > s1_115) {
+ int var23 = -890798748;
+ do {
+ ++var23;
+ long long e_119[4];
+ } while (var23 <= -890798746);
+ }
+ } while (var22 <= -1141190829);
+ }
+ } while (var13 <= 1960990946);
+ }
+ } while (var8 <= -161498254);
+ } while (var6 <= -1267827462);
+ }
Index: gcc/testsuite/gcc.dg/torture/pr70288-2.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr70288-2.c (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr70288-2.c (working copy)
***************
*** 0 ****
--- 1,35 ----
+ /* { dg-do compile } */
+ /* { dg-require-effective-target int32plus } */
+
+ int main()
+ {
+ int var6 = -1267827473;
+ do {
+ ++var6;
+ double s1_115[4], s2_108[4];
+ int var8 = -161498264;
+ do {
+ ++var8;
+ int var12 = 1260960076;
+ for (; var12 <= 1260960080; ++var12) {
+ int var13 = 1960990937;
+ do {
+ ++var13;
+ int var14 = 2128638723;
+ for (; var14 <= 2128638728; ++var14) {
+ int var22 = -1141190839;
+ do {
+ ++var22;
+ if (s2_108 > s1_115) {
+ int var23 = -890798748;
+ do {
+ long long e_119[4];
+ } while (var23 <= -890798746);
+ }
+ } while (var22 <= -1141190829);
+ }
+ } while (var13 <= 1960990946);
+ }
+ } while (var8 <= -161498254);
+ } while (var6 <= -1267827462);
+ }
More information about the Gcc-patches
mailing list