]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR go/91617 (Many go test case failures after r275026)
authorJakub Jelinek <jakub@redhat.com>
Mon, 21 Oct 2019 11:36:36 +0000 (13:36 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 21 Oct 2019 11:36:36 +0000 (13:36 +0200)
Backported from mainline
2019-09-02  Jakub Jelinek  <jakub@redhat.com>

PR go/91617
* fold-const.c (range_check_type): For enumeral and boolean
type, pass 1 to type_for_size langhook instead of
TYPE_UNSIGNED (etype).  Return unsigned_type_for result whenever
etype isn't TYPE_UNSIGNED INTEGER_TYPE.
(build_range_check): Don't call unsigned_type_for for pointer types.
* match.pd (X / C1 op C2): Don't call unsigned_type_for on
range_check_type result.

2019-08-29  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/91351
* tree-cfg.c (generate_range_test): Use range_check_type instead of
unsigned_type_for.
* tree-cfgcleanup.c (convert_single_case_switch): Punt if
range_check_type returns NULL.
* tree-switch-conversion.c (switch_conversion::build_one_array):
Use range_check_type instead of unsigned_type_for, don't perform
linear opt if it returns NULL.
(bit_test_cluster::find_bit_tests): Formatting fix.
(bit_test_cluster::emit): Use range_check_type instead of
unsigned_type_for.
(switch_decision_tree::try_switch_expansion): Punt if range_check_type
returns NULL.

* g++.dg/opt/pr91351.C: New test.

From-SVN: r277244

gcc/ChangeLog
gcc/fold-const.c
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr91351.C [new file with mode: 0644]
gcc/tree-cfg.c
gcc/tree-cfgcleanup.c
gcc/tree-switch-conversion.c

index ca0db0bce3451cf5d0afe997dad3beb03dcbfd16..7242fd804a16dcdfad76ba0d1f9c86d732a9834e 100644 (file)
@@ -1,3 +1,33 @@
+2019-10-21  Jakub Jelinek  <jakub@redhat.com>
+
+       Backported from mainline
+       2019-09-02  Jakub Jelinek  <jakub@redhat.com>
+
+       PR go/91617
+       * fold-const.c (range_check_type): For enumeral and boolean
+       type, pass 1 to type_for_size langhook instead of
+       TYPE_UNSIGNED (etype).  Return unsigned_type_for result whenever
+       etype isn't TYPE_UNSIGNED INTEGER_TYPE.
+       (build_range_check): Don't call unsigned_type_for for pointer types.
+       * match.pd (X / C1 op C2): Don't call unsigned_type_for on
+       range_check_type result.
+
+       2019-08-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/91351
+       * tree-cfg.c (generate_range_test): Use range_check_type instead of
+       unsigned_type_for.
+       * tree-cfgcleanup.c (convert_single_case_switch): Punt if
+       range_check_type returns NULL.
+       * tree-switch-conversion.c (switch_conversion::build_one_array):
+       Use range_check_type instead of unsigned_type_for, don't perform
+       linear opt if it returns NULL.
+       (bit_test_cluster::find_bit_tests): Formatting fix.
+       (bit_test_cluster::emit): Use range_check_type instead of
+       unsigned_type_for.
+       (switch_decision_tree::try_switch_expansion): Punt if range_check_type
+       returns NULL.
+
 2019-10-18  Georg-Johann Lay  <avr@gjlay.de>
 
        Backport from 2019-10-18 trunk r277143.
index f0e43b5fda239326630f17ef3ab33562c39461a3..9feaea9fde57222e06c155b4a5284511ffa12a45 100644 (file)
@@ -4935,10 +4935,9 @@ range_check_type (tree etype)
   /* First make sure that arithmetics in this type is valid, then make sure
      that it wraps around.  */
   if (TREE_CODE (etype) == ENUMERAL_TYPE || TREE_CODE (etype) == BOOLEAN_TYPE)
-    etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
-                                           TYPE_UNSIGNED (etype));
+    etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), 1);
 
-  if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_OVERFLOW_WRAPS (etype))
+  if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_UNSIGNED (etype))
     {
       tree utype, minv, maxv;
 
@@ -4956,6 +4955,8 @@ range_check_type (tree etype)
       else
        return NULL_TREE;
     }
+  else if (POINTER_TYPE_P (etype))
+    etype = unsigned_type_for (etype);
   return etype;
 }
 
@@ -5046,9 +5047,6 @@ build_range_check (location_t loc, tree type, tree exp, int in_p,
   if (etype == NULL_TREE)
     return NULL_TREE;
 
-  if (POINTER_TYPE_P (etype))
-    etype = unsigned_type_for (etype);
-
   high = fold_convert_loc (loc, etype, high);
   low = fold_convert_loc (loc, etype, low);
   exp = fold_convert_loc (loc, etype, exp);
index 039ddacfed1e849dc8e101239110f98207fbdd48..533082196a2fe3ce8b5cf4102dc3f8e1455dc153 100644 (file)
@@ -1519,8 +1519,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        tree etype = range_check_type (TREE_TYPE (@0));
        if (etype)
          {
-           if (! TYPE_UNSIGNED (etype))
-             etype = unsigned_type_for (etype);
            hi = fold_convert (etype, hi);
            lo = fold_convert (etype, lo);
            hi = const_binop (MINUS_EXPR, etype, hi, lo);
index 84aaff44669437bcedeccefbbb4494a7ae294805..6b55e4372313ea8bdb91908f5a6ff1f4c4b87846 100644 (file)
@@ -1,6 +1,11 @@
 2019-10-21  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-08-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/91351
+       * g++.dg/opt/pr91351.C: New test.
+
        2019-08-09  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/91401
diff --git a/gcc/testsuite/g++.dg/opt/pr91351.C b/gcc/testsuite/g++.dg/opt/pr91351.C
new file mode 100644 (file)
index 0000000..f793a2f
--- /dev/null
@@ -0,0 +1,38 @@
+// PR tree-optimization/91351
+// { dg-do run }
+// { dg-options "-O2 -fstrict-enums" }
+
+enum E { e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12,
+        e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25 };
+
+__attribute__((noipa)) void
+foo ()
+{
+  __builtin_abort ();
+}
+
+__attribute__((noipa)) void
+bar ()
+{
+}
+
+__attribute__((noipa)) void
+baz (E e)
+{
+  switch (e)
+    {
+    case e11:
+    case e12:
+    case e13: foo (); break;
+    case e24: break;
+    case e14:
+    case e15: break;
+    default: bar (); break;
+    }
+}
+
+int
+main ()
+{
+  baz (e3);
+}
index 32be59acfb06cbc285a01326ce34009eb9b9151b..d27cc65f8837cf54b84b347d8b79236c7ee0b244 100644 (file)
@@ -9151,7 +9151,7 @@ generate_range_test (basic_block bb, tree index, tree low, tree high,
                     tree *lhs, tree *rhs)
 {
   tree type = TREE_TYPE (index);
-  tree utype = unsigned_type_for (type);
+  tree utype = range_check_type (type);
 
   low = fold_convert (utype, low);
   high = fold_convert (utype, high);
index 183b491ab1d3ccd0e448e16b1fb5df652cfec8ff..4bac38ab00c742441d11aa9dd7839cb3ec2451da 100644 (file)
@@ -101,6 +101,8 @@ convert_single_case_switch (gswitch *swtch, gimple_stmt_iterator &gsi)
   if (high)
     {
       tree lhs, rhs;
+      if (range_check_type (TREE_TYPE (index)) == NULL_TREE)
+       return false;
       generate_range_test (bb, index, low, high, &lhs, &rhs);
       cond = gimple_build_cond (LE_EXPR, lhs, rhs, NULL_TREE, NULL_TREE);
     }
index c3f2baf39d70de39180311c7cc36dfe282b865eb..dd6dd8064de43390a25a508f3df3691754648e63 100644 (file)
@@ -605,7 +605,9 @@ switch_conversion::build_one_array (int num, tree arr_index_type,
   vec<constructor_elt, va_gc> *constructor = m_constructors[num];
   wide_int coeff_a, coeff_b;
   bool linear_p = contains_linear_function_p (constructor, &coeff_a, &coeff_b);
-  if (linear_p)
+  tree type;
+  if (linear_p
+      && (type = range_check_type (TREE_TYPE ((*constructor)[0].value))))
     {
       if (dump_file && coeff_a.to_uhwi () > 0)
        fprintf (dump_file, "Linear transformation with A = %" PRId64
@@ -613,13 +615,12 @@ switch_conversion::build_one_array (int num, tree arr_index_type,
                 coeff_b.to_shwi ());
 
       /* We must use type of constructor values.  */
-      tree t = unsigned_type_for (TREE_TYPE ((*constructor)[0].value));
       gimple_seq seq = NULL;
-      tree tmp = gimple_convert (&seq, t, m_index_expr);
-      tree tmp2 = gimple_build (&seq, MULT_EXPR, t,
-                               wide_int_to_tree (t, coeff_a), tmp);
-      tree tmp3 = gimple_build (&seq, PLUS_EXPR, t, tmp2,
-                               wide_int_to_tree (t, coeff_b));
+      tree tmp = gimple_convert (&seq, type, m_index_expr);
+      tree tmp2 = gimple_build (&seq, MULT_EXPR, type,
+                               wide_int_to_tree (type, coeff_a), tmp);
+      tree tmp3 = gimple_build (&seq, PLUS_EXPR, type, tmp2,
+                               wide_int_to_tree (type, coeff_b));
       tree tmp4 = gimple_convert (&seq, TREE_TYPE (name), tmp3);
       gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
       load = gimple_build_assign (name, tmp4);
@@ -1350,7 +1351,7 @@ bit_test_cluster::find_bit_tests (vec<cluster *> &clusters)
                                                  entire));
        }
       else
-       for (int i = end - 1; i >=  start; i--)
+       for (int i = end - 1; i >= start; i--)
          output.safe_push (clusters[i]);
 
       end = start;
@@ -1483,7 +1484,7 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
   unsigned int i, j, k;
   unsigned int count;
 
-  tree unsigned_index_type = unsigned_type_for (index_type);
+  tree unsigned_index_type = range_check_type (index_type);
 
   gimple_stmt_iterator gsi;
   gassign *shift_stmt;
@@ -1793,7 +1794,8 @@ switch_decision_tree::try_switch_expansion (vec<cluster *> &clusters)
   tree index_type = TREE_TYPE (index_expr);
   basic_block bb = gimple_bb (m_switch);
 
-  if (gimple_switch_num_labels (m_switch) == 1)
+  if (gimple_switch_num_labels (m_switch) == 1
+      || range_check_type (index_type) == NULL_TREE)
     return false;
 
   /* Find the default case target label.  */