Fix -O2 vs. -O1 missed optimizations in VN

Message ID alpine.LSU.2.20.1907101520300.2976@zhemvz.fhfr.qr
State New
Headers show
Series
  • Fix -O2 vs. -O1 missed optimizations in VN
Related show

Commit Message

Richard Biener July 10, 2019, 1:22 p.m.
The "do fancy stuff" routine failed to look at the valueized LHS
in some cases which makes it regress at -O2 compared to -O1
(because with -O1 all preceeding stmts have gone through elimination
already).

Noticed when working on aarch64 support for PR83518.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2019-07-10  Richard Biener  <rguenther@suse.de>

	c/
	* gimple-parser.c (c_parser_gimple_postfix_expression): Support
	_Literal (int *) &x for address literals.

	* tree-ssa-sccvn.c (vn_reference_lookup_3): Look at valueized
	LHS whenever possible.

	* gcc.dg/torture/ssa-fre-5.c: New testcase.
	* gcc.dg/torture/ssa-fre-6.c: Likewise.
	* gcc.dg/torture/ssa-fre-7.c: Likewise.

Patch

Index: gcc/c/gimple-parser.c
===================================================================
--- gcc/c/gimple-parser.c	(revision 273353)
+++ gcc/c/gimple-parser.c	(working copy)
@@ -1606,8 +1606,10 @@  c_parser_gimple_postfix_expression (gimp
 		  tree val = c_parser_gimple_postfix_expression (parser).value;
 		  if (! val
 		      || val == error_mark_node
-		      || ! CONSTANT_CLASS_P (val)
-		      || (addr_p && TREE_CODE (val) != STRING_CST))
+		      || (!CONSTANT_CLASS_P (val)
+			  && !(addr_p
+			       && (TREE_CODE (val) == STRING_CST
+				   || DECL_P (val)))))
 		    {
 		      c_parser_error (parser, "invalid _Literal");
 		      return expr;
Index: gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/ssa-fre-5.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/ssa-fre-5.c	(working copy)
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* { dg-additional-options "-fgimple -fdump-tree-fre1" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+
+int __GIMPLE (ssa,startwith("fre"))
+foo ()
+{
+  int * p;
+  int i;
+  int x[4];
+  long unsigned int _1;
+  long unsigned int _2;
+  int _7;
+
+  __BB(2):
+  i_3 = 0;
+  _1 = (long unsigned int) i_3;
+  _2 = _1 * 4ul;
+  p_4 = _Literal (int *) &x + _2;
+  __MEM <v4si> ((v4si *)p_4) = _Literal (v4si) { 1, 2, 3, 4 };
+  _7 = x[0];
+  return _7;
+}
+
+/* { dg-final { scan-tree-dump "return 1;" "fre1" } } */
Index: gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/ssa-fre-6.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/ssa-fre-6.c	(working copy)
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* { dg-additional-options "-fgimple -fdump-tree-fre1" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+
+int __GIMPLE (ssa,startwith("fre"))
+foo ()
+{
+  int * p;
+  int i;
+  int x[4];
+  long unsigned int _1;
+  long unsigned int _2;
+  int _7;
+
+  __BB(2):
+  i_3 = 0;
+  _1 = (long unsigned int) i_3;
+  _2 = _1 * 4ul;
+  p_4 = _Literal (int *) &x + _2;
+  __MEM <v4si> ((v4si *)p_4) = _Literal (v4si) {};
+  _7 = x[0];
+  return _7;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */
Index: gcc/testsuite/gcc.dg/torture/ssa-fre-7.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/ssa-fre-7.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/ssa-fre-7.c	(working copy)
@@ -0,0 +1,29 @@ 
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* { dg-additional-options "-fgimple -fdump-tree-fre1" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+
+int __GIMPLE (ssa,startwith("fre"))
+foo (int c)
+{
+  int * p;
+  int i;
+  int x[4];
+  long unsigned int _1;
+  long unsigned int _2;
+  int _7;
+  v4si _6;
+
+  __BB(2):
+  i_3 = 0;
+  _1 = (long unsigned int) i_3;
+  _2 = _1 * 4ul;
+  p_4 = _Literal (int *) &x + _2;
+  _6 = _Literal (v4si) { c_5(D), c_5(D), c_5(D), c_5(D) };
+  __MEM <v4si> ((v4si *)p_4) = _6;
+  _7 = x[0];
+  return _7;
+}
+
+/* { dg-final { scan-tree-dump "return c_5\\(D\\);" "fre1" } } */
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	(revision 273353)
+++ gcc/tree-ssa-sccvn.c	(working copy)
@@ -2488,12 +2488,22 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 	   && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
 	   && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0)
     {
+      tree lhs = gimple_assign_lhs (def_stmt);
       tree base2;
       poly_int64 offset2, size2, maxsize2;
       HOST_WIDE_INT offset2i, size2i;
       bool reverse;
-      base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
-				       &offset2, &size2, &maxsize2, &reverse);
+      if (lhs_ref_ok)
+	{
+	  base2 = ao_ref_base (&lhs_ref);
+	  offset2 = lhs_ref.offset;
+	  size2 = lhs_ref.size;
+	  maxsize2 = lhs_ref.max_size;
+	  reverse = reverse_storage_order_for_component_p (lhs);
+	}
+      else
+	base2 = get_ref_base_and_extent (lhs,
+					 &offset2, &size2, &maxsize2, &reverse);
       if (known_size_p (maxsize2)
 	  && known_eq (maxsize2, size2)
 	  && adjust_offsets_for_equal_base_address (base, &offset,
@@ -2541,12 +2551,22 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 	       || (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
 		   && is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt))))))
     {
+      tree lhs = gimple_assign_lhs (def_stmt);
       tree base2;
       poly_int64 offset2, size2, maxsize2;
       HOST_WIDE_INT offset2i, size2i;
       bool reverse;
-      base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
-				       &offset2, &size2, &maxsize2, &reverse);
+      if (lhs_ref_ok)
+	{
+	  base2 = ao_ref_base (&lhs_ref);
+	  offset2 = lhs_ref.offset;
+	  size2 = lhs_ref.size;
+	  maxsize2 = lhs_ref.max_size;
+	  reverse = reverse_storage_order_for_component_p (lhs);
+	}
+      else
+	base2 = get_ref_base_and_extent (lhs,
+					 &offset2, &size2, &maxsize2, &reverse);
       if (base2
 	  && !reverse
 	  && known_eq (maxsize2, size2)
@@ -2627,12 +2647,21 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 	      downstream, not so much for actually doing the insertion.  */
 	   && data->partial_defs.is_empty ())
     {
+      tree lhs = gimple_assign_lhs (def_stmt);
       tree base2;
       poly_int64 offset2, size2, maxsize2;
       bool reverse;
-      base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
-				       &offset2, &size2, &maxsize2,
-				       &reverse);
+      if (lhs_ref_ok)
+	{
+	  base2 = ao_ref_base (&lhs_ref);
+	  offset2 = lhs_ref.offset;
+	  size2 = lhs_ref.size;
+	  maxsize2 = lhs_ref.max_size;
+	  reverse = reverse_storage_order_for_component_p (lhs);
+	}
+      else
+	base2 = get_ref_base_and_extent (lhs,
+					 &offset2, &size2, &maxsize2, &reverse);
       tree def_rhs = gimple_assign_rhs1 (def_stmt);
       if (!reverse
 	  && known_size_p (maxsize2)