diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
index cc3a8899d97ed6b50fd605a5ad16913d0a28b458..9cf29701c06597f55273dc10b124b5a40474084a 100644
--- a/gcc/c/gimple-parser.cc
+++ b/gcc/c/gimple-parser.cc
@@ -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
index 0000000000000000000000000000000000000000..03db786b6195328059b804bd8d03413e05970e98
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-50.c
@@ -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
index 0000000000000000000000000000000000000000..16e69c11228e19aaa46b371473eb5d253e111830
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-51.c
@@ -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;
+}