re PR tree-optimization/81503 (Wrong code at -O2)
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Tue, 29 Aug 2017 14:41:53 +0000 (14:41 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Tue, 29 Aug 2017 14:41:53 +0000 (14:41 +0000)
[gcc]

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-08-29  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

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

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
Co-Authored-By: Richard Biener <rguenther@suse.de>
From-SVN: r251414

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 7fc2f55..f1037f6 100644 (file)
@@ -1,3 +1,11 @@
+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-29  Martin Liska  <mliska@suse.cz>
 
        * passes.def: Include pass_lower_switch.
index 9adb455..8fe7c17 100644 (file)
@@ -2089,104 +2089,104 @@ 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 != SSA_NAME
-      && !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 == SSA_NAME
+      || 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 (wi::neg_p (bump))
+    {
+      code = MINUS_EXPR;
+      bump = -bump;
+    }
+
+  /* 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 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 (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fputs ("Replacing: ", dump_file);
+      print_gimple_stmt (dump_file, c->cand_stmt, 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);
+      slsr_cand_t cc = c;
+      gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
+      gsi_replace (&gsi, copy_stmt, false);
+      c->cand_stmt = copy_stmt;
+      while (cc->next_interp)
+       {
+         cc = lookup_cand (cc->next_interp);
+         cc->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))))
        {
-         fputs ("Replacing: ", dump_file);
-         print_gimple_stmt (dump_file, c->cand_stmt, 0);
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fputs ("(duplicate, not actually replacing)", dump_file);
+             stmt_to_print = c->cand_stmt;
+           }
        }
-
-      if (bump == 0)
+      else
        {
-         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);
          slsr_cand_t cc = c;
-         gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
-         gsi_replace (&gsi, copy_stmt, false);
-         c->cand_stmt = copy_stmt;
+         gimple_assign_set_rhs_with_ops (&gsi, code, basis_name, bump_tree);
+         update_stmt (gsi_stmt (gsi));
+         c->cand_stmt = gsi_stmt (gsi);
          while (cc->next_interp)
            {
              cc = lookup_cand (cc->next_interp);
-             cc->cand_stmt = copy_stmt;
+             cc->cand_stmt = gsi_stmt (gsi);
            }
          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))))
-           {
-             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);
-             slsr_cand_t cc = c;
-             gimple_assign_set_rhs_with_ops (&gsi, code,
-                                             basis_name, bump_tree);
-             update_stmt (gsi_stmt (gsi));
-              c->cand_stmt = gsi_stmt (gsi);
-             while (cc->next_interp)
-               {
-                 cc = lookup_cand (cc->next_interp);
-                 cc->cand_stmt = gsi_stmt (gsi);
-               }
-             if (dump_file && (dump_flags & TDF_DETAILS))
-               stmt_to_print = gsi_stmt (gsi);
-           }
+           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);
-         fputs ("\n", dump_file);
-       }
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fputs ("With: ", dump_file);
+      print_gimple_stmt (dump_file, stmt_to_print, 0);
+      fputs ("\n", dump_file);
     }
 }
 
index 5888d28..23fc398 100644 (file)
@@ -1,3 +1,8 @@
+2017-08-29  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       PR tree-optimization/81503
+       * gcc.c-torture/execute/pr81503.c: New file.
+
 2017-08-29  Martin Liska  <mliska@suse.cz>
 
        * gcc.dg/tree-prof/update-loopch.c: Scan patterns in
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;
+}