public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v1 1/2] Simplify shifts wider than the bitwidth of types
@ 2020-11-16 18:57 Philipp Tomsich
  2020-11-16 18:57 ` [PATCH v1 2/2] RISC-V: Adjust predicates for immediate shift operands Philipp Tomsich
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Philipp Tomsich @ 2020-11-16 18:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: Philipp Tomsich

From: Philipp Tomsich <prt@gnu.org>

While most shifts wider than the bitwidth of a type will be caught by
other passes, it is possible that these show up for VRP.
Consider the following example:
  int func (int a, int b, int c)
  {
    return (a << ((b && c) - 1));
  }

This adds simplify_using_ranges::simplify_lshift_using_ranges to
detect and rewrite such cases.  If the intersection of meaningful
shift amounts for the underlying type and the value-range computed
for the shift-amount (whether an integer constant or a variable) is
empty, the statement is replaced with the zero-constant of the same
precision as the result.

gcc/ChangeLog:

       * vr-values.h (simplify_using_ranges): Declare.
       * vr-values.c (simplify_lshift_using_ranges): New function.
       (simplify): Use simplify_lshift_using_ranges for LSHIFT_EXPR.

---

 gcc/ChangeLog   |  6 ++++++
 gcc/vr-values.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/vr-values.h |  1 +
 3 files changed, 66 insertions(+)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 89317d4..b8b9beb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-11-16  Philipp Tomsich  <prt@gnu.org>
+
+	* vr-values.h (simplify_using_ranges): Declare.
+	* vr-values.c (simplify_lshift_using_ranges): New function.
+	(simplify): Use simplify_lshift_using_ranges for LSHIFT_EXPR.
+
 2020-11-13  Jan Hubicka  <jh@suse.cz>
 
 	* tree-ssa-alias.c (ao_ref_base_alias_ptr_type): Remove accidental
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 9f5943a..da7208e 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -3318,6 +3318,58 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges
   return false;
 }
 
+/* Simplify a lshift, if the shift-amount is larger than the
+   bit-width of the type.  Return true if we do simplify.  */
+bool
+simplify_using_ranges::simplify_lshift_using_ranges
+				(gimple_stmt_iterator *gsi,
+				 gimple *stmt)
+{
+  tree op0 = gimple_assign_rhs1 (stmt);
+  tree op1 = gimple_assign_rhs2 (stmt);
+  value_range vr1;
+
+  /* We only support integral types.  */
+  if (INTEGRAL_TYPE_P (op0))
+    return false;
+
+  if (TREE_CODE (op1) == INTEGER_CST)
+    vr1.set (op1);
+  else if (TREE_CODE (op1) == SSA_NAME)
+    vr1 = *(query->get_value_range (op1, stmt));
+  else
+    return false;
+
+  if (vr1.varying_p () || vr1.undefined_p ())
+    return false;
+
+  /* Shift amounts are valid up to the type precision.  Any shift that
+     is outside of the range [0, type precision - 1] can be rewritten
+     to a constant result.  */
+  const unsigned prec = TYPE_PRECISION (TREE_TYPE (op0));
+  value_range valid (build_zero_cst (TREE_TYPE (op1)),
+		     build_int_cst (TREE_TYPE (op1), prec - 1),
+		     VR_RANGE);
+
+  valid.intersect (vr1);
+  if (valid.undefined_p ())
+    {
+      /* If the intersection is empty (i.e. undefined), then we can replace the
+	 shift with the zero-constant.  */
+
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	{
+	  fprintf (dump_file, "\nReplacing shift beyond precision in stmt: ");
+	  print_gimple_stmt (dump_file, stmt, 0);
+	}
+      gimple_assign_set_rhs_from_tree (gsi, build_zero_cst (TREE_TYPE (op0)));
+      update_stmt (gsi_stmt (*gsi));
+      return true;
+    }
+
+  return false;
+}
+
 /* Simplify a min or max if the ranges of the two operands are
    disjoint.   Return true if we do simplify.  */
 
@@ -4422,6 +4474,13 @@ simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
 	case MAX_EXPR:
 	  return simplify_min_or_max_using_ranges (gsi, stmt);
 
+	case LSHIFT_EXPR:
+	  if ((TREE_CODE (rhs1) == SSA_NAME
+	       || TREE_CODE (rhs1) == INTEGER_CST)
+	      && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
+	    return simplify_lshift_using_ranges (gsi, stmt);
+	  break;
+
 	default:
 	  break;
 	}
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 59fac0c..18fd5c1 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -48,6 +48,7 @@ private:
   bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_abs_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *);
+  bool simplify_lshift_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_cond_using_ranges_1 (gcond *);
   bool fold_cond (gcond *);
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2020-11-18 23:47 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-16 18:57 [PATCH v1 1/2] Simplify shifts wider than the bitwidth of types Philipp Tomsich
2020-11-16 18:57 ` [PATCH v1 2/2] RISC-V: Adjust predicates for immediate shift operands Philipp Tomsich
2020-11-16 22:27   ` Jim Wilson
2020-11-16 22:45     ` Philipp Tomsich
2020-11-17 17:06       ` Jim Wilson
2020-11-16 22:38 ` [PATCH v1 1/2] Simplify shifts wider than the bitwidth of types Jim Wilson
2020-11-16 22:59   ` Philipp Tomsich
2020-11-16 23:38 ` Jeff Law
2020-11-17 11:53   ` Philipp Tomsich
2020-11-17 15:56     ` Jeff Law
2020-11-17 16:29       ` Philipp Tomsich
2020-11-17 16:46         ` Jakub Jelinek
2020-11-17 16:54           ` Jeff Law
2020-11-17 16:58             ` Jakub Jelinek
2020-11-18 23:46               ` Jeff Law
2020-11-17 17:23             ` Philipp Tomsich
2020-11-17 18:02               ` Jakub Jelinek
2020-11-17 17:14           ` Jim Wilson
2020-11-17 17:55             ` Jakub Jelinek
2020-11-17 16:35       ` Philipp Tomsich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).