]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR tree-optimization/81503 (Wrong code at -O2)
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Tue, 5 Sep 2017 21:52:01 +0000 (21:52 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Tue, 5 Sep 2017 21:52:01 +0000 (21:52 +0000)
[gcc]

2017-09-05  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

Backport from mainline
2017-08-29  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
    Jakub Jelinek  <jakub@redhat.com>
    Richard Biener  <rguenther@suse.de>

PR tree-optimization/81503
* gimple-ssa-strength-reduction.c (replace_mult_candidate): Ensure
folded constant fits in the target type; reorder tests for clarity.

[gcc/testsuite]

2017-09-05  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

Backport from mainline
2017-08-29  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
    Jakub Jelinek  <jakub@redhat.com>
    Richard Biener  <rguenther@suse.de>

PR tree-optimization/81503
* gcc.c-torture/execute/pr81503.c: New file.

From-SVN: r251745

gcc/ChangeLog
gcc/gimple-ssa-strength-reduction.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr81503.c [new file with mode: 0644]

index f1dcf48b372e78afae6fb3034d9cc07355c6c121..06aeb5bb3d5fa5ef7808423e86369a60500742ff 100644 (file)
@@ -1,3 +1,14 @@
+2017-09-05  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       Backport from mainline
+       2017-08-29  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+                   Jakub Jelinek  <jakub@redhat.com>
+                   Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/81503
+       * gimple-ssa-strength-reduction.c (replace_mult_candidate): Ensure
+       folded constant fits in the target type; reorder tests for clarity.
+
 2017-08-22  Peter Bergner  <bergner@vnet.ibm.com>
 
        Backport from mainline
index 8f7c56d6085a40511a5a0eb3a2fc5f163ae9cc3c..63f1e6b1fd7730d8490389695928fb659461156d 100644 (file)
@@ -2041,92 +2041,92 @@ replace_mult_candidate (slsr_cand_t c, tree basis_name, widest_int bump)
   tree target_type = TREE_TYPE (gimple_assign_lhs (c->cand_stmt));
   enum tree_code cand_code = gimple_assign_rhs_code (c->cand_stmt);
 
-  /* It is highly unlikely, but possible, that the resulting
-     bump doesn't fit in a HWI.  Abandon the replacement
-     in this case.  This does not affect siblings or dependents
-     of C.  Restriction to signed HWI is conservative for unsigned
-     types but allows for safe negation without twisted logic.  */
-  if (wi::fits_shwi_p (bump)
-      && bump.to_shwi () != HOST_WIDE_INT_MIN
-      /* It is not useful to replace casts, copies, negates, or adds of
-        an SSA name and a constant.  */
-      && cand_code != MODIFY_EXPR
-      && !CONVERT_EXPR_CODE_P (cand_code)
-      && cand_code != PLUS_EXPR
-      && cand_code != POINTER_PLUS_EXPR
-      && cand_code != MINUS_EXPR
-      && cand_code != NEGATE_EXPR)
-    {
-      enum tree_code code = PLUS_EXPR;
-      tree bump_tree;
-      gimple stmt_to_print = NULL;
+  /* It is not useful to replace casts, copies, negates, or adds of
+     an SSA name and a constant.  */
+  if (cand_code == MODIFY_EXPR
+      || CONVERT_EXPR_CODE_P (cand_code)
+      || cand_code == PLUS_EXPR
+      || cand_code == POINTER_PLUS_EXPR
+      || cand_code == MINUS_EXPR
+      || cand_code == NEGATE_EXPR)
+    return;
 
-      /* If the basis name and the candidate's LHS have incompatible
-        types, introduce a cast.  */
-      if (!useless_type_conversion_p (target_type, TREE_TYPE (basis_name)))
-       basis_name = introduce_cast_before_cand (c, target_type, basis_name);
-      if (wi::neg_p (bump))
-       {
-         code = MINUS_EXPR;
-         bump = -bump;
-       }
+  enum tree_code code = PLUS_EXPR;
+  tree bump_tree;
+  gimple stmt_to_print = NULL;
 
-      bump_tree = wide_int_to_tree (target_type, bump);
+  /* If the basis name and the candidate's LHS have incompatible
+     types, introduce a cast.  */
+  if (!useless_type_conversion_p (target_type, TREE_TYPE (basis_name)))
+    basis_name = introduce_cast_before_cand (c, target_type, basis_name);
+  if (wi::neg_p (bump))
+    {
+      code = MINUS_EXPR;
+      bump = -bump;
+    }
 
-      if (dump_file && (dump_flags & TDF_DETAILS))
-       {
-         fputs ("Replacing: ", dump_file);
-         print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
-       }
+ /* It is possible that the resulting bump doesn't fit in target_type.
+    Abandon the replacement in this case.  This does not affect
+    siblings or dependents of C.  */
+  if (bump != wi::ext (bump, TYPE_PRECISION (target_type),
+                      TYPE_SIGN (target_type)))
+    return;
+
+  bump_tree = wide_int_to_tree (target_type, bump);
 
-      if (bump == 0)
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fputs ("Replacing: ", dump_file);
+      print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
+    }
+
+  if (bump == 0)
+    {
+      tree lhs = gimple_assign_lhs (c->cand_stmt);
+      gassign *copy_stmt = gimple_build_assign (lhs, basis_name);
+      gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
+      gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
+      gsi_replace (&gsi, copy_stmt, false);
+      c->cand_stmt = copy_stmt;
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       stmt_to_print = copy_stmt;
+    }
+  else
+    {
+      tree rhs1, rhs2;
+      if (cand_code != NEGATE_EXPR) {
+       rhs1 = gimple_assign_rhs1 (c->cand_stmt);
+       rhs2 = gimple_assign_rhs2 (c->cand_stmt);
+      }
+      if (cand_code != NEGATE_EXPR
+         && ((operand_equal_p (rhs1, basis_name, 0)
+              && operand_equal_p (rhs2, bump_tree, 0))
+             || (operand_equal_p (rhs1, bump_tree, 0)
+                 && operand_equal_p (rhs2, basis_name, 0))))
        {
-         tree lhs = gimple_assign_lhs (c->cand_stmt);
-         gassign *copy_stmt = gimple_build_assign (lhs, basis_name);
-         gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
-         gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
-         gsi_replace (&gsi, copy_stmt, false);
-         c->cand_stmt = copy_stmt;
          if (dump_file && (dump_flags & TDF_DETAILS))
-           stmt_to_print = copy_stmt;
+           {
+             fputs ("(duplicate, not actually replacing)", dump_file);
+             stmt_to_print = c->cand_stmt;
+           }
        }
       else
        {
-         tree rhs1, rhs2;
-         if (cand_code != NEGATE_EXPR) {
-           rhs1 = gimple_assign_rhs1 (c->cand_stmt);
-           rhs2 = gimple_assign_rhs2 (c->cand_stmt);
-         }
-         if (cand_code != NEGATE_EXPR
-             && ((operand_equal_p (rhs1, basis_name, 0)
-                  && operand_equal_p (rhs2, bump_tree, 0))
-                 || (operand_equal_p (rhs1, bump_tree, 0)
-                     && operand_equal_p (rhs2, basis_name, 0))))
-           {
-             if (dump_file && (dump_flags & TDF_DETAILS))
-               {
-                 fputs ("(duplicate, not actually replacing)", dump_file);
-                 stmt_to_print = c->cand_stmt;
-               }
-           }
-         else
-           {
-             gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
-             gimple_assign_set_rhs_with_ops (&gsi, code,
-                                             basis_name, bump_tree);
-             update_stmt (gsi_stmt (gsi));
-              c->cand_stmt = gsi_stmt (gsi);
-             if (dump_file && (dump_flags & TDF_DETAILS))
-               stmt_to_print = gsi_stmt (gsi);
-           }
+         gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
+         gimple_assign_set_rhs_with_ops (&gsi, code,
+                                         basis_name, bump_tree);
+         update_stmt (gsi_stmt (gsi));
+         c->cand_stmt = gsi_stmt (gsi);
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           stmt_to_print = gsi_stmt (gsi);
        }
+    }
   
-      if (dump_file && (dump_flags & TDF_DETAILS))
-       {
-         fputs ("With: ", dump_file);
-         print_gimple_stmt (dump_file, stmt_to_print, 0, 0);
-         fputs ("\n", dump_file);
-       }
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fputs ("With: ", dump_file);
+      print_gimple_stmt (dump_file, stmt_to_print, 0, 0);
+      fputs ("\n", dump_file);
     }
 }
 
index 00747512c05b210994eecc5d3c20ad09fb0bdfb2..b3ce0469ee5e29e0d747fc4d0cc1ab8ab4249c84 100644 (file)
@@ -1,3 +1,13 @@
+2017-09-05  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       Backport from mainline
+       2017-08-29  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+                   Jakub Jelinek  <jakub@redhat.com>
+                   Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/81503
+       * gcc.c-torture/execute/pr81503.c: New file.
+
 2017-09-02  Janus Weil  <janus@gcc.gnu.org>
 
        Backport from trunk
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr81503.c b/gcc/testsuite/gcc.c-torture/execute/pr81503.c
new file mode 100644 (file)
index 0000000..5fc6cb0
--- /dev/null
@@ -0,0 +1,15 @@
+unsigned short a = 41461;
+unsigned short b = 3419;
+int c = 0;
+
+void foo() {
+  if (a + b * ~(0 != 5))
+    c = -~(b * ~(0 != 5)) + 2147483647;
+}
+
+int main() {
+  foo();
+  if (c != 2147476810)
+    return -1;
+  return 0;
+}