c/111975 - GIMPLE FE dumping and parsing of TARGET_MEM_REF

The following adds dumping of TARGET_MEM_REF in -gimple form and
adds parsing of it to the GIMPLE FE.

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

gcc/
	* tree-pretty-print.cc (dump_mem_ref): Use TDF_GIMPLE path
	also for TARGET_MEM_REF and amend it.

gcc/testsuite/
	* gcc.dg/gimplefe-52.c: New testcase.
This commit is contained in:
Richard Biener 2023-12-18 11:41:03 +01:00
parent 8c5d1d1388
commit 5bca321faa
3 changed files with 101 additions and 10 deletions

View file

@ -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)

View file

@ -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;
}

View file

@ -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