]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c/111468 - add unordered compare and pointer diff to GIMPLE FE parsing
authorRichard Biener <rguenther@suse.de>
Tue, 19 Sep 2023 09:49:54 +0000 (11:49 +0200)
committerRichard Biener <rguenther@suse.de>
Tue, 19 Sep 2023 11:01:05 +0000 (13:01 +0200)
The following adds __UN{LT,LE,GT,GE,EQ}, __UNORDERED and __ORDERED
operator parsing support and support for parsing - as POINTER_DIFF_EXPR.

PR c/111468
gcc/c/
* gimple-parser.cc (c_parser_gimple_binary_expression): Add
return type argument.
(c_parser_gimple_statement): Adjust.
(c_parser_gimple_paren_condition): Likewise.
(c_parser_gimple_binary_expression): Use passed in return type,
add support for - as POINTER_DIFF_EXPR, __UN{LT,LE,GT,GE,EQ},
__UNORDERED and __ORDERED.

gcc/testsuite/
* gcc.dg/gimplefe-50.c: New testcase.
* gcc.dg/gimplefe-51.c: Likewise.

gcc/c/gimple-parser.cc
gcc/testsuite/gcc.dg/gimplefe-50.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gimplefe-51.c [new file with mode: 0644]

index cc3a8899d97ed6b50fd605a5ad16913d0a28b458..9cf29701c06597f55273dc10b124b5a40474084a 100644 (file)
@@ -108,7 +108,7 @@ gimple_parser::push_edge (int src, int dest, int flags,
 static bool c_parser_gimple_compound_statement (gimple_parser &, gimple_seq *);
 static void c_parser_gimple_label (gimple_parser &, gimple_seq *);
 static void c_parser_gimple_statement (gimple_parser &, gimple_seq *);
-static struct c_expr c_parser_gimple_binary_expression (gimple_parser &);
+static struct c_expr c_parser_gimple_binary_expression (gimple_parser &, tree);
 static struct c_expr c_parser_gimple_unary_expression (gimple_parser &);
 static struct c_expr c_parser_gimple_postfix_expression (gimple_parser &);
 static struct c_expr c_parser_gimple_postfix_expression_after_primary
@@ -869,7 +869,7 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq)
       return;
     }
 
-  rhs = c_parser_gimple_binary_expression (parser);
+  rhs = c_parser_gimple_binary_expression (parser, TREE_TYPE (lhs.value));
   if (lhs.value != error_mark_node
       && rhs.value != error_mark_node)
     {
@@ -930,7 +930,7 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq)
 */
 
 static c_expr
-c_parser_gimple_binary_expression (gimple_parser &parser)
+c_parser_gimple_binary_expression (gimple_parser &parser, tree ret_type)
 {
   /* Location of the binary operator.  */
   struct c_expr ret, lhs, rhs;
@@ -939,7 +939,6 @@ c_parser_gimple_binary_expression (gimple_parser &parser)
   lhs = c_parser_gimple_postfix_expression (parser);
   if (c_parser_error (parser))
     return ret;
-  tree ret_type = TREE_TYPE (lhs.value);
   switch (c_parser_peek_token (parser)->type)
     {
     case CPP_MULT:
@@ -958,7 +957,10 @@ c_parser_gimple_binary_expression (gimple_parser &parser)
        code = PLUS_EXPR;
       break;
     case CPP_MINUS:
-      code = MINUS_EXPR;
+      if (POINTER_TYPE_P (TREE_TYPE (lhs.value)))
+       code = POINTER_DIFF_EXPR;
+      else
+       code = MINUS_EXPR;
       break;
     case CPP_LSHIFT:
       code = LSHIFT_EXPR;
@@ -968,27 +970,21 @@ c_parser_gimple_binary_expression (gimple_parser &parser)
       break;
     case CPP_LESS:
       code = LT_EXPR;
-      ret_type = boolean_type_node;
       break;
     case CPP_GREATER:
       code = GT_EXPR;
-      ret_type = boolean_type_node;
       break;
     case CPP_LESS_EQ:
       code = LE_EXPR;
-      ret_type = boolean_type_node;
       break;
     case CPP_GREATER_EQ:
       code = GE_EXPR;
-      ret_type = boolean_type_node;
       break;
     case CPP_EQ_EQ:
       code = EQ_EXPR;
-      ret_type = boolean_type_node;
       break;
     case CPP_NOT_EQ:
       code = NE_EXPR;
-      ret_type = boolean_type_node;
       break;
     case CPP_AND:
       code = BIT_AND_EXPR;
@@ -1006,14 +1002,49 @@ c_parser_gimple_binary_expression (gimple_parser &parser)
       c_parser_error (parser, "%<||%> not valid in GIMPLE");
       return ret;
     case CPP_NAME:
-       {
-         tree id = c_parser_peek_token (parser)->value;
-         if (strcmp (IDENTIFIER_POINTER (id), "__MULT_HIGHPART") == 0)
-           {
-             code = MULT_HIGHPART_EXPR;
-             break;
-           }
-       }
+      {
+       tree id = c_parser_peek_token (parser)->value;
+       if (strcmp (IDENTIFIER_POINTER (id), "__MULT_HIGHPART") == 0)
+         {
+           code = MULT_HIGHPART_EXPR;
+           break;
+         }
+       else if (strcmp (IDENTIFIER_POINTER (id), "__UNLT") == 0)
+         {
+           code = UNLT_EXPR;
+           break;
+         }
+       else if (strcmp (IDENTIFIER_POINTER (id), "__UNLE") == 0)
+         {
+           code = UNLE_EXPR;
+           break;
+         }
+       else if (strcmp (IDENTIFIER_POINTER (id), "__UNGT") == 0)
+         {
+           code = UNGT_EXPR;
+           break;
+         }
+       else if (strcmp (IDENTIFIER_POINTER (id), "__UNGE") == 0)
+         {
+           code = UNGE_EXPR;
+           break;
+         }
+       else if (strcmp (IDENTIFIER_POINTER (id), "__UNEQ") == 0)
+         {
+           code = UNEQ_EXPR;
+           break;
+         }
+       else if (strcmp (IDENTIFIER_POINTER (id), "__UNORDERED") == 0)
+         {
+           code = UNORDERED_EXPR;
+           break;
+         }
+       else if (strcmp (IDENTIFIER_POINTER (id), "__ORDERED") == 0)
+         {
+           code = ORDERED_EXPR;
+           break;
+         }
+      }
       /* Fallthru.  */
     default:
       /* Not a binary expression.  */
@@ -2158,7 +2189,8 @@ c_parser_gimple_paren_condition (gimple_parser &parser)
 {
   if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     return error_mark_node;
-  tree cond = c_parser_gimple_binary_expression (parser).value;
+  tree cond
+    = c_parser_gimple_binary_expression (parser, boolean_type_node).value;
   if (cond != error_mark_node
       && ! COMPARISON_CLASS_P (cond)
       && ! CONSTANT_CLASS_P (cond)
diff --git a/gcc/testsuite/gcc.dg/gimplefe-50.c b/gcc/testsuite/gcc.dg/gimplefe-50.c
new file mode 100644 (file)
index 0000000..03db786
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+void __GIMPLE (ssa)
+foo (float a, float b)
+{
+  _Bool x;
+
+ __BB(2):
+  x_3 = a_1(D) __UNLT b_2(D);
+  x_4 = a_1(D) __UNLE b_2(D);
+  x_5 = a_1(D) __UNGT b_2(D);
+  x_6 = a_1(D) __UNGE b_2(D);
+  x_7 = a_1(D) __UNEQ b_2(D);
+  x_8 = a_1(D) __UNORDERED b_2(D);
+  x_9 = a_1(D) __ORDERED b_2(D);
+  if (a_1(D) __UNEQ b_2(D))
+    goto __BB4;
+  else
+    goto __BB3;
+
+ __BB(3):
+  goto __BB4;
+
+ __BB(4):
+  return;
+}
diff --git a/gcc/testsuite/gcc.dg/gimplefe-51.c b/gcc/testsuite/gcc.dg/gimplefe-51.c
new file mode 100644 (file)
index 0000000..16e69c1
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+__PTRDIFF_TYPE__ __GIMPLE (ssa)
+foo (void *p, void *q)
+{
+  __PTRDIFF_TYPE__ d;
+
+ __BB(2):
+  d_3 = p_1(D) - q_2(D);
+  return d_3;
+}