https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90078

            Bug ID: 90078
           Summary: ICE with deep templates caused by overflow [PATCH]
           Product: gcc
           Version: tree-ssa
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wlandry at caltech dot edu
  Target Milestone: ---

Created attachment 46160
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46160&action=edit
Failing test case

Compiling the attached code with

  g++ -O2 ftensorShowcase.cpp -c -ftemplate-depth=1000000

fails with the internal compiler error below.  Using godbolt, it seems that
this bug started in gcc 7.1 and is still present in trunk.

In gcc/tree-ssa-loop-ivopts.c, there is a cost struct that has a concept of
infinity.  For very deep, recursive templates, the cost can get larger than
'infinity' (10000000).  The diff below against trunk implements saturating
arithmetic.  It seems to work.

Thanks.

==============================================


diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index a2b6b2b2312..a89782b13d0 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -276,7 +276,11 @@ comp_cost::operator+= (HOST_WIDE_INT c)
   if (infinite_cost_p ())
     return *this;

-  this->cost += c;
+  /* Switch around comparison to avoid overflow */
+  if (c > infinite_cost.cost - this->cost)
+    this->cost = infinite_cost.cost;
+  else
+    this->cost += c;

   return *this;
 }
@@ -287,7 +291,11 @@ comp_cost::operator-= (HOST_WIDE_INT c)
   if (infinite_cost_p ())
     return *this;

-  this->cost -= c;
+  /* Switch around comparison to avoid overflow */
+  if (c < -infinite_cost.cost + this->cost )
+    this->cost = infinite_cost.cost;
+  else
+    this->cost -= c;

   return *this;
 }
@@ -298,7 +306,10 @@ comp_cost::operator/= (HOST_WIDE_INT c)
   if (infinite_cost_p ())
     return *this;

-  this->cost /= c;
+  if (c == 0)
+    this->cost = infinite_cost.cost;
+  else
+    this->cost /= c;

   return *this;
 }
@@ -309,7 +320,11 @@ comp_cost::operator*= (HOST_WIDE_INT c)
   if (infinite_cost_p ())
     return *this;

-  this->cost *= c;
+  /* Switch around comparison to avoid overflow */
+  if (c > infinite_cost.cost / this->cost )
+    this->cost = infinite_cost.cost;
+  else
+    this->cost *= c;

   return *this;
 }


==============================================

during GIMPLE pass: ivopts
ftensorShowcase.cpp: In member function ‘auto& Tensor4_Expr<Tensor4<A, Dim0,
Dim1, Dim2, Dim3>, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l>::operator=(const
Tensor4_Expr<B, U, Dim1_0, Dim1_1, Dim1_2, Dim1_3, i_1, j_1, k_1, l_1>&) [with
B = Tensor3_times_Tensor3_21<const Tensor3<float, 100, 100, 1000>, const
Tensor3<float, 1000, 100, 100>, float, float, 100, 100, 1000, 100, 100, 'l',
'm', 'k', 'n', 'o'>; U = float; int Dim1_0 = 100; int Dim1_1 = 100; int Dim1_2
= 100; int Dim1_3 = 100; char i_1 = 'l'; char j_1 = 'm'; char k_1 = 'n'; char
l_1 = 'o'; A = float; T = float; int Dim0 = 100; int Dim1 = 100; int Dim2 =
100; int Dim3 = 100; char i = 'l'; char j = 'm'; char k = 'n'; char l = 'o']’:
ftensorShowcase.cpp:170:9: internal compiler error: in try_improve_iv_set, at
tree-ssa-loop-ivopts.c:6667
   auto &operator=(const Tensor4_Expr<B, U, Dim1_0, Dim1_1, Dim1_2, Dim1_3,
i_1,
         ^~~~~~~~
0x7f878289509a __libc_start_main
        ../csu/libc-start.c:308
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <file:///usr/share/doc/gcc-8/README.Bugs> for instructions.

Reply via email to