c/111975 - GIMPLE FE dumping and parsing of TARGET_MEM_REF

Message ID 20231218115136.6F3DF3857C50@sourceware.org
State Committed
Commit 5bca321faa30c4fb46225efbe2698a13b3271b1c
Headers
Series c/111975 - GIMPLE FE dumping and parsing of TARGET_MEM_REF |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm warning Patch is already merged
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 warning Patch is already merged

Commit Message

Richard Biener Dec. 18, 2023, 11:50 a.m. UTC
  The following adds dumping of TARGET_MEM_REF in -gimple form and
adds parsing of it to the GIMPLE FE.

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

	PR c/111975
gcc/c/
	* gimple-parser.cc (c_parser_gimple_postfix_expression):
	Parse TARGET_MEM_REF extended operands for __MEM.

gcc/testsuite/
	* gcc.dg/gimplefe-52.c: New testcase.
---
 gcc/c/gimple-parser.cc             | 66 ++++++++++++++++++++++++++----
 gcc/testsuite/gcc.dg/gimplefe-52.c | 21 ++++++++++
 gcc/tree-pretty-print.cc           | 24 ++++++++++-
 3 files changed, 101 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gimplefe-52.c
  

Patch

diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
index 72bff1cb305..87ed336e45d 100644
--- a/gcc/c/gimple-parser.cc
+++ b/gcc/c/gimple-parser.cc
@@ -1487,9 +1487,12 @@  c_parser_gimple_postfix_expression (gimple_parser &parser)
 	      location_t loc = c_parser_peek_token (parser)->location;
 	      c_parser_consume_token (parser);
 	      tree type = c_parser_gimple_typespec (parser);
-	      struct c_expr ptr;
+	      struct c_expr ptr, alias_off, step, index, index2;
 	      ptr.value = error_mark_node;
-	      tree alias_off = NULL_TREE;
+	      alias_off.value = NULL_TREE;
+	      step.value = NULL_TREE;
+	      index.value = NULL_TREE;
+	      index2.value = NULL_TREE;
 	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
 		{
 		  tree alias_type = NULL_TREE;
@@ -1525,12 +1528,52 @@  c_parser_gimple_postfix_expression (gimple_parser &parser)
 		  if (c_parser_next_token_is (parser, CPP_PLUS))
 		    {
 		      c_parser_consume_token (parser);
-		      alias_off
-			= c_parser_gimple_postfix_expression (parser).value;
-		      alias_off = fold_convert (alias_type, alias_off);
+		      alias_off = c_parser_gimple_postfix_expression (parser);
+		    }
+		  if (c_parser_next_token_is (parser, CPP_MULT))
+		    {
+		      std::swap (index, alias_off);
+		      c_parser_consume_token (parser);
+		      step = c_parser_gimple_postfix_expression (parser);
+		    }
+		  else if (c_parser_next_token_is (parser, CPP_PLUS))
+		    {
+		      c_parser_consume_token (parser);
+		      index = c_parser_gimple_postfix_expression (parser);
+		      if (c_parser_next_token_is (parser, CPP_MULT))
+			{
+			  c_parser_consume_token (parser);
+			  step = c_parser_gimple_postfix_expression (parser);
+			}
+		      else
+			std::swap (index, index2);
+		    }
+		  else if (alias_off.value
+			   && TREE_CODE (alias_off.value) != INTEGER_CST)
+		    std::swap (alias_off, index2);
+		  if (c_parser_next_token_is (parser, CPP_PLUS))
+		    {
+		      c_parser_consume_token (parser);
+		      index2 = c_parser_gimple_postfix_expression (parser);
+		    }
+		  if (alias_off.value)
+		    {
+		      if (TREE_CODE (alias_off.value) != INTEGER_CST)
+			error_at (alias_off.get_start (),
+				  "expected constant offset for %<__MEM%> "
+				  "operand");
+		      alias_off.value = fold_convert (alias_type,
+						      alias_off.value);
+		    }
+		  else
+		    alias_off.value = build_int_cst (alias_type, 0);
+		  if (step.value)
+		    {
+		      if (TREE_CODE (step.value) != INTEGER_CST)
+			error_at (step.get_start (),
+				  "expected constant step for %<__MEM%> "
+				  "operand");
 		    }
-		  if (! alias_off)
-		    alias_off = build_int_cst (alias_type, 0);
 		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
 					     "expected %<)%>");
 		}
@@ -1539,8 +1582,13 @@  c_parser_gimple_postfix_expression (gimple_parser &parser)
 		  c_parser_set_error (parser, false);
 		  return expr;
 		}
-	      expr.value = build2_loc (loc, MEM_REF,
-				       type, ptr.value, alias_off);
+	      if (index.value || step.value || index2.value)
+		expr.value = build5_loc (loc, TARGET_MEM_REF,
+					 type, ptr.value, alias_off.value,
+					 index.value, step.value, index2.value);
+	      else
+		expr.value = build2_loc (loc, MEM_REF,
+					 type, ptr.value, alias_off.value);
 	      break;
 	    }
 	  else if (strcmp (IDENTIFIER_POINTER (id), "__VIEW_CONVERT") == 0)
diff --git a/gcc/testsuite/gcc.dg/gimplefe-52.c b/gcc/testsuite/gcc.dg/gimplefe-52.c
new file mode 100644
index 00000000000..8b85aacd6b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-52.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+int x;
+
+float __GIMPLE ()
+foo (int * p, __UINTPTR_TYPE__ idx, __UINTPTR_TYPE__ idx2)
+{
+  float f;
+  float D1800;
+  unsigned int D1799;
+
+  D1799 = __MEM <unsigned int, 8> ((char *)p + 1 + idx * _Literal (__SIZETYPE__) 2);
+  __MEM <unsigned int, 16> ((char *)&f + 0xfffffffffffffffe) = D1799;
+  __MEM <int> (&x + idx2) = 1;
+  __MEM <int, 2> (p + idx * _Literal (__SIZETYPE__) 1) = 1;
+  __MEM <int> (&x + 2 + idx2) = 1;
+  __MEM <int> ((char *)&x + 4 + idx * _Literal (__SIZETYPE__) 4 + idx2) = 1;
+  D1800 = f;
+  return D1800;
+}
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 68857ae1cdf..86a7d162eae 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -1687,7 +1687,9 @@  dump_omp_atomic_memory_order (pretty_printer *pp, enum omp_memory_order mo)
 static void
 dump_mem_ref (pretty_printer *pp, tree node, int spc, dump_flags_t flags)
 {
-  if (TREE_CODE (node) == MEM_REF && (flags & TDF_GIMPLE))
+  if ((TREE_CODE (node) == MEM_REF
+       || TREE_CODE (node) == TARGET_MEM_REF)
+      && (flags & TDF_GIMPLE))
     {
       pp_string (pp, "__MEM <");
       dump_generic_node (pp, TREE_TYPE (node),
@@ -1716,6 +1718,26 @@  dump_mem_ref (pretty_printer *pp, tree node, int spc, dump_flags_t flags)
 	  dump_generic_node (pp, TREE_OPERAND (node, 1),
 			     spc, flags | TDF_SLIM, false);
 	}
+      if (TREE_CODE (node) == TARGET_MEM_REF)
+	{
+	  if (TREE_OPERAND (node, 2))
+	    {
+	      /* INDEX * STEP  */
+	      pp_string (pp, " + ");
+	      dump_generic_node (pp, TREE_OPERAND (node, 2),
+				 spc, flags | TDF_SLIM, false);
+	      pp_string (pp, " * ");
+	      dump_generic_node (pp, TREE_OPERAND (node, 3),
+				 spc, flags | TDF_SLIM, false);
+	    }
+	  if (TREE_OPERAND (node, 4))
+	    {
+	      /* INDEX2  */
+	      pp_string (pp, " + ");
+	      dump_generic_node (pp, TREE_OPERAND (node, 4),
+				 spc, flags | TDF_SLIM, false);
+	    }
+	}
       pp_right_paren (pp);
     }
   else if (TREE_CODE (node) == MEM_REF