c/118742 - gimple FE parsing of unary operators of C promoted args

Message ID 20250204120628.F3E613858414@sourceware.org
State New
Headers
Series c/118742 - gimple FE parsing of unary operators of C promoted args |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Richard Biener Feb. 4, 2025, 12:05 p.m. UTC
  The GIMPLE FE currently invokes parser_build_unary_op to build
unary GENERIC which has the operand subject to C promotion rules
which does not match GIMPLE.  The following adds a wrapper around
the build_unary_op worker which conveniently has an argument to
indicate whether to skip such promotion.

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

	PR c/118742
gcc/c/
	* gimple-parser.cc (gimple_parser_build_unary_op): New
	wrapper around build_unary_op.
	(c_parser_gimple_unary_expression): Use it.

	* gcc.dg/gimplefe-56.c: New testcase.
---
 gcc/c/gimple-parser.cc             | 49 +++++++++++++++++++++++++-----
 gcc/testsuite/gcc.dg/gimplefe-56.c | 24 +++++++++++++++
 2 files changed, 65 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gimplefe-56.c
  

Patch

diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
index 54ecf22151c..90b9beb1e9f 100644
--- a/gcc/c/gimple-parser.cc
+++ b/gcc/c/gimple-parser.cc
@@ -125,6 +125,39 @@  static tree c_parser_gimple_paren_condition (gimple_parser &);
 static void c_parser_gimple_expr_list (gimple_parser &, vec<tree> *);
 
 
+/* Much like parser_build_unary_op, but avoid applying default conversions.  */
+
+static c_expr
+gimple_parser_build_unary_op (location_t loc,
+			      enum tree_code code, struct c_expr arg)
+{
+  struct c_expr result;
+
+  result.original_code = code;
+  result.original_type = NULL;
+  result.m_decimal = 0;
+
+  if (reject_gcc_builtin (arg.value))
+    {
+      result.value = error_mark_node;
+    }
+  else
+    {
+      result.value = build_unary_op (loc, code, arg.value, true);
+
+      if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
+	overflow_warning (loc, result.value, arg.value);
+    }
+
+  /* We are typically called when parsing a prefix token at LOC acting on
+     ARG.  Reflect this by updating the source range of the result to
+     start at LOC and end at the end of ARG.  */
+  set_c_expr_source_range (&result,
+			   loc, arg.get_finish ());
+
+  return result;
+}
+
 /* See if VAL is an identifier matching __BB<num> and return <num>
    in *INDEX.  */
 
@@ -1203,7 +1236,7 @@  c_parser_gimple_unary_expression (gimple_parser &parser)
       c_parser_consume_token (parser);
       op = c_parser_gimple_postfix_expression (parser);
       mark_exp_read (op.value);
-      return parser_build_unary_op (op_loc, ADDR_EXPR, op);
+      return gimple_parser_build_unary_op (op_loc, ADDR_EXPR, op);
     case CPP_MULT:
       {
 	c_parser_consume_token (parser);
@@ -1228,15 +1261,15 @@  c_parser_gimple_unary_expression (gimple_parser &parser)
     case CPP_PLUS:
       c_parser_consume_token (parser);
       op = c_parser_gimple_postfix_expression (parser);
-      return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
+      return gimple_parser_build_unary_op (op_loc, CONVERT_EXPR, op);
     case CPP_MINUS:
       c_parser_consume_token (parser);
       op = c_parser_gimple_postfix_expression (parser);
-      return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
+      return gimple_parser_build_unary_op (op_loc, NEGATE_EXPR, op);
     case CPP_COMPL:
       c_parser_consume_token (parser);
       op = c_parser_gimple_postfix_expression (parser);
-      return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
+      return gimple_parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
     case CPP_NOT:
       c_parser_error (parser, "%<!%> not valid in GIMPLE");
       return ret;
@@ -1246,11 +1279,11 @@  c_parser_gimple_unary_expression (gimple_parser &parser)
 	case RID_REALPART:
 	  c_parser_consume_token (parser);
 	  op = c_parser_gimple_postfix_expression (parser);
-	  return parser_build_unary_op (op_loc, REALPART_EXPR, op);
+	  return gimple_parser_build_unary_op (op_loc, REALPART_EXPR, op);
 	case RID_IMAGPART:
 	  c_parser_consume_token (parser);
 	  op = c_parser_gimple_postfix_expression (parser);
-	  return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
+	  return gimple_parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
 	default:
 	  return c_parser_gimple_postfix_expression (parser);
 	}
@@ -1261,13 +1294,13 @@  c_parser_gimple_unary_expression (gimple_parser &parser)
 	    {
 	      c_parser_consume_token (parser);
 	      op = c_parser_gimple_postfix_expression (parser);
-	      return parser_build_unary_op (op_loc, ABS_EXPR, op);
+	      return gimple_parser_build_unary_op (op_loc, ABS_EXPR, op);
 	    }
 	  else if (strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0)
 	    {
 	      c_parser_consume_token (parser);
 	      op = c_parser_gimple_postfix_expression (parser);
-	      return parser_build_unary_op (op_loc, ABSU_EXPR, op);
+	      return gimple_parser_build_unary_op (op_loc, ABSU_EXPR, op);
 	    }
 	  else if (strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0)
 	    return c_parser_gimple_parentized_binary_expression (parser,
diff --git a/gcc/testsuite/gcc.dg/gimplefe-56.c b/gcc/testsuite/gcc.dg/gimplefe-56.c
new file mode 100644
index 00000000000..72c66ae463d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-56.c
@@ -0,0 +1,24 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+_Bool __GIMPLE (ssa,startwith("optimized")) g1(int i)
+{
+  _Bool _1;
+  _Bool _2;
+
+  __BB(2):
+  _1 = i_3(D) == 1;
+  _2 = ~_1;
+  return _2;
+}
+
+signed char __GIMPLE (ssa,startwith("optimized")) g2(signed char i)
+{
+  signed char _1;
+  signed char _2;
+
+  __BB(2):
+  _1 = i_3(D);
+  _2 = -_1;
+  return _2;
+}