c/111468 - add unordered compare and pointer diff to GIMPLE FE parsing
Checks
Commit Message
The following adds __UN{LT,LE,GT,GE,EQ}, __UNORDERED and __ORDERED
operator parsing support and support for parsing - as POINTER_DIFF_EXPR.
Bootstrapped and tested on x86_64-unknown-linux-gnu, will push later.
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.dg/gimplefe-50.c: New testcase.
* gcc.dg/gimplefe-51.c: Likewise.
---
gcc/c/gimple-parser.cc | 72 +++++++++++++++++++++---------
gcc/testsuite/gcc.dg/gimplefe-50.c | 27 +++++++++++
gcc/testsuite/gcc.dg/gimplefe-51.c | 12 +++++
3 files changed, 91 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-50.c
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-51.c
@@ -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)
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}