This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Fold floating-point comparisons


This patch implements the optimizations that Roger suggested in his message "[PATCH] Document a bunch of expression tree codes", and in general makes GCC able to combine floating-point comparisons. For example,

int f(float f, float g)
{
  return !__builtin_isunordered (f, g) && (f != g);
}

is folded to a single <> (i.e. __builtin_islessgreater) call. Are the floating-point mavens among you thinking that it is incorrect? If so, read on cause that's what I wanted...

I'm posting this as a RFC because I am not sure at all on which floating-point comparisons may trap, which affects the validity of the transformation in the -ftrapping-math case. The places to look at are the new combine_comparisons function in fold-const.c, and the implementation of the expander for the new tree code LTGT_EXPR, in dojump.c.

Regtests are still to be written.

Paolo

2004-05-26  Paolo Bonzini  <bonzini@gnu.org>
	    Roger Sayle  <roger@eyesopen.com>

	Add LTGT_EXPR and improve pretty-printing of unordered
	comparisons.
	* c-common.c (c_common_truthvalue_conversion):
	Handle LTGT_EXPR.
	* c-typeck.c (build_binary_op): Likewise.
	* dojump.c (do_jump): Likewise.
	* expr.c (expand_expr_real_1, do_store_flag): Likewise.
	* predict.c (tree_predict_by_opcode): Likewise.
	* real.c (real_compare): Likewise.
	* tree-cfg.c (verify_expr): Likewise.
	* tree-inline.c (estimate_num_insns_1): Likewise.
	* tree-pretty-print.c (dump_generic_node): Likewise.
	Handle ORDERED_EXPR, UNORDERED_EXPR.
	(op_symbol): Print unordered comparisons differently
	than ordered ones.
	* tree.def (LTGT_EXPR): New '<' tree code.

	Fold comparisons between floating point values.
	* fold-const.c (enum comparison_code): New, from
	#define'd constants.  Define compcodes for unordered
	comparisons and for invalid transformations.
	(invert_tree_comparison): Add "honor_nans" parameter.
	(fold_truthop): Revamp to work on floating-point types too.
	(comparison_to_compcode): Support unordered comparisons.
	Use new enum comparison_code.
	(compcode_to_comparison): Likewise.
	(combine_compcodes): New function.
	(invert_truthvalue): Let invert_tree_comparison decide
	whether it is valid to fold the comparison.  Fold ORDERED
	and UNORDERED even if flag_unsafe_math_optimizations is off.
	(fold_relational_const): Integer modes do not honor NaNs.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.501
diff -u -p -r1.501 c-common.c
--- c-common.c	22 May 2004 18:16:38 -0000	1.501
+++ c-common.c	26 May 2004 14:31:05 -0000
@@ -2582,7 +2582,7 @@ c_common_truthvalue_conversion (tree exp
 
   switch (TREE_CODE (expr))
     {
-    case EQ_EXPR:   case NE_EXPR:   case UNEQ_EXPR:
+    case EQ_EXPR:   case NE_EXPR:   case UNEQ_EXPR: case LTGT_EXPR:
     case LE_EXPR:   case GE_EXPR:   case LT_EXPR:   case GT_EXPR:
     case UNLE_EXPR: case UNGE_EXPR: case UNLT_EXPR: case UNGT_EXPR:
     case ORDERED_EXPR: case UNORDERED_EXPR:
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.304
diff -u -p -r1.304 c-typeck.c
--- c-typeck.c	14 May 2004 02:32:55 -0000	1.304
+++ c-typeck.c	26 May 2004 14:31:06 -0000
@@ -6798,6 +6798,7 @@ build_binary_op (enum tree_code code, tr
     case UNGT_EXPR:
     case UNGE_EXPR:
     case UNEQ_EXPR:
+    case LTGT_EXPR:
       build_type = integer_type_node;
       if (code0 != REAL_TYPE || code1 != REAL_TYPE)
 	{
Index: dojump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dojump.c,v
retrieving revision 1.16
diff -u -p -r1.16 dojump.c
--- dojump.c	29 Apr 2004 07:50:55 -0000	1.16
+++ dojump.c	26 May 2004 14:31:08 -0000
@@ -525,7 +525,8 @@ do_jump (tree exp, rtx if_false_label, r
 
     {
       enum rtx_code rcode1;
-      enum tree_code tcode2;
+      enum tree_code tcode1 = UNORDERED_EXPR, tcode2;
+      enum tree_code tcode_final = TRUTH_ORIF_EXPR;
 
       case UNLT_EXPR:
         rcode1 = UNLT;
@@ -547,6 +548,12 @@ do_jump (tree exp, rtx if_false_label, r
         rcode1 = UNEQ;
         tcode2 = EQ_EXPR;
         goto unordered_bcc;
+      case LTGT_EXPR:
+        rcode1 = LTGT;
+        tcode1 = ORDERED_EXPR;
+        tcode2 = NE_EXPR;
+	tcode_final = TRUTH_ANDIF_EXPR;
+        goto unordered_bcc;
 
       unordered_bcc:
         mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
@@ -560,10 +567,10 @@ do_jump (tree exp, rtx if_false_label, r
             tree cmp0, cmp1;
 
             /* If the target doesn't support combined unordered
-               compares, decompose into UNORDERED + comparison.  */
-            cmp0 = fold (build (UNORDERED_EXPR, TREE_TYPE (exp), op0, op1));
+               compares, decompose into two comparisons.  */
+            cmp0 = fold (build (tcode1, TREE_TYPE (exp), op0, op1));
             cmp1 = fold (build (tcode2, TREE_TYPE (exp), op0, op1));
-            exp = build (TRUTH_ORIF_EXPR, TREE_TYPE (exp), cmp0, cmp1);
+            exp = build (tcode_final, TREE_TYPE (exp), cmp0, cmp1);
             do_jump (exp, if_false_label, if_true_label);
           }
       }
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.647
diff -u -p -r1.647 expr.c
--- expr.c	19 May 2004 06:26:21 -0000	1.647
+++ expr.c	26 May 2004 14:31:10 -0000
@@ -8304,6 +8304,7 @@ expand_expr_real_1 (tree exp, rtx target
     case UNGT_EXPR:
     case UNGE_EXPR:
     case UNEQ_EXPR:
+    case LTGT_EXPR:
       temp = do_store_flag (exp,
 			    modifier != EXPAND_STACK_PARM ? target : NULL_RTX,
 			    tmode != VOIDmode ? tmode : mode, 0);
@@ -9814,6 +9815,9 @@ do_store_flag (tree exp, rtx target, enu
     case UNEQ_EXPR:
       code = UNEQ;
       break;
+    case LTGT_EXPR:
+      code = LTGT;
+      break;
 
     default:
       abort ();
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.382
diff -u -p -r1.382 fold-const.c
--- fold-const.c	24 May 2004 03:02:44 -0000	1.382
+++ fold-const.c	26 May 2004 14:31:12 -0000
@@ -58,6 +58,29 @@ Software Foundation, 59 Temple Place - S
 #include "langhooks.h"
 #include "md5.h"
 
+/* The following constants represent a bit based encoding of GCC's
+   comparison operators.  This encoding simplifies transformations
+   on relational comparison operators, such as AND and OR.  */
+enum comparison_code {
+  COMPCODE_INVALID = -1,
+  COMPCODE_FALSE = 0,
+  COMPCODE_LT = 1,
+  COMPCODE_EQ = 2,
+  COMPCODE_LE = 3,
+  COMPCODE_GT = 4,
+  COMPCODE_LTGT = 5,
+  COMPCODE_GE = 6,
+  COMPCODE_ORD = 7,
+  COMPCODE_UNORD = 8,
+  COMPCODE_UNLT = 9,
+  COMPCODE_UNEQ = 10,
+  COMPCODE_UNLE = 11,
+  COMPCODE_UNGT = 12,
+  COMPCODE_NE = 13,
+  COMPCODE_UNGE = 14,
+  COMPCODE_TRUE = 15
+};
+
 static void encode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT, HOST_WIDE_INT);
 static void decode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
 static bool negate_mathfn_p (enum built_in_function);
@@ -69,10 +92,12 @@ static tree const_binop (enum tree_code,
 static hashval_t size_htab_hash (const void *);
 static int size_htab_eq (const void *, const void *);
 static tree fold_convert_const (enum tree_code, tree, tree);
-static enum tree_code invert_tree_comparison (enum tree_code);
+static enum tree_code invert_tree_comparison (enum tree_code, bool);
 static enum tree_code swap_tree_comparison (enum tree_code);
-static int comparison_to_compcode (enum tree_code);
-static enum tree_code compcode_to_comparison (int);
+static enum comparison_code comparison_to_compcode (enum tree_code);
+static enum tree_code compcode_to_comparison (enum comparison_code);
+static enum comparison_code combine_comparisons (enum tree_code, enum tree_code,
+						 enum tree_code, bool);
 static int truth_value_p (enum tree_code);
 static int operand_equal_for_comparison_p (tree, tree, tree);
 static int twoval_comparison_p (tree, tree *, tree *, int *);
@@ -115,18 +140,6 @@ static tree fold_abs_const (tree, tree);
 static tree fold_relational_const (enum tree_code, tree, tree, tree);
 static tree fold_relational_hi_lo (enum tree_code *, const tree, tree *, tree *);
 
-/* The following constants represent a bit based encoding of GCC's
-   comparison operators.  This encoding simplifies transformations
-   on relational comparison operators, such as AND and OR.  */
-#define COMPCODE_FALSE   0
-#define COMPCODE_LT      1
-#define COMPCODE_EQ      2
-#define COMPCODE_LE      3
-#define COMPCODE_GT      4
-#define COMPCODE_NE      5
-#define COMPCODE_GE      6
-#define COMPCODE_TRUE    7
-
 /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
    overflow.  Suppose A, B and SUM have the same respective signs as A1, B1,
    and SUM1.  Then this yields nonzero if overflow occurred during the
@@ -2057,11 +2070,15 @@ pedantic_non_lvalue (tree x)
 
 /* Given a tree comparison code, return the code that is the logical inverse
    of the given code.  It is not safe to do this for floating-point
-   comparisons, except for NE_EXPR and EQ_EXPR.  */
+   comparisons, except for NE_EXPR and EQ_EXPR, so we receive a machine mode
+   as well: if reversing the comparison is unsafe, return ERROR_MARK.  */
 
 static enum tree_code
-invert_tree_comparison (enum tree_code code)
+invert_tree_comparison (enum tree_code code, bool honor_nans)
 {
+  if (honor_nans && flag_trapping_math)
+    return ERROR_MARK;
+
   switch (code)
     {
     case EQ_EXPR:
@@ -2069,13 +2086,29 @@ invert_tree_comparison (enum tree_code c
     case NE_EXPR:
       return EQ_EXPR;
     case GT_EXPR:
-      return LE_EXPR;
+      return honor_nans ? UNLE_EXPR : LE_EXPR;
     case GE_EXPR:
-      return LT_EXPR;
+      return honor_nans ? UNLT_EXPR : LT_EXPR;
     case LT_EXPR:
-      return GE_EXPR;
+      return honor_nans ? UNGE_EXPR : GE_EXPR;
     case LE_EXPR:
+      return honor_nans ? UNGT_EXPR : GT_EXPR;
+    case LTGT_EXPR:
+      return UNEQ_EXPR;
+    case UNEQ_EXPR:
+      return LTGT_EXPR;
+    case UNGT_EXPR:
+      return LE_EXPR;
+    case UNGE_EXPR:
+      return LT_EXPR;
+    case UNLT_EXPR:
+      return GE_EXPR;
+    case UNLE_EXPR:
       return GT_EXPR;
+    case ORDERED_EXPR:
+      return UNORDERED_EXPR;
+    case UNORDERED_EXPR:
+      return ORDERED_EXPR;
     default:
       abort ();
     }
@@ -2110,7 +2143,7 @@ swap_tree_comparison (enum tree_code cod
    into a compcode bit-based encoding.  This function is the inverse of
    compcode_to_comparison.  */
 
-static int
+static enum comparison_code
 comparison_to_compcode (enum tree_code code)
 {
   switch (code)
@@ -2127,6 +2160,22 @@ comparison_to_compcode (enum tree_code c
       return COMPCODE_NE;
     case GE_EXPR:
       return COMPCODE_GE;
+    case ORDERED_EXPR:
+      return COMPCODE_ORD;
+    case UNORDERED_EXPR:
+      return COMPCODE_UNORD;
+    case UNLT_EXPR:
+      return COMPCODE_UNLT;
+    case UNEQ_EXPR:
+      return COMPCODE_UNEQ;
+    case UNLE_EXPR:
+      return COMPCODE_UNLE;
+    case UNGT_EXPR:
+      return COMPCODE_UNGT;
+    case LTGT_EXPR:
+      return COMPCODE_LTGT;
+    case UNGE_EXPR:
+      return COMPCODE_UNGE;
     default:
       abort ();
     }
@@ -2137,7 +2186,7 @@ comparison_to_compcode (enum tree_code c
    inverse of comparison_to_compcode.  */
 
 static enum tree_code
-compcode_to_comparison (int code)
+compcode_to_comparison (enum comparison_code code)
 {
   switch (code)
     {
@@ -2153,11 +2202,74 @@ compcode_to_comparison (int code)
       return NE_EXPR;
     case COMPCODE_GE:
       return GE_EXPR;
+    case COMPCODE_ORD:
+      return ORDERED_EXPR;
+    case COMPCODE_UNORD:
+      return UNORDERED_EXPR;
+    case COMPCODE_UNLT:
+      return UNLT_EXPR;
+    case COMPCODE_UNEQ:
+      return UNEQ_EXPR;
+    case COMPCODE_UNLE:
+      return UNLE_EXPR;
+    case COMPCODE_UNGT:
+      return UNGT_EXPR;
+    case COMPCODE_LTGT:
+      return LTGT_EXPR;
+    case COMPCODE_UNGE:
+      return UNGE_EXPR;
     default:
       abort ();
     }
 }
 
+/* Return a bit-based comparison code which is the combination of
+   doing the AND or OR (depending on CODE) of the two operations
+   LCODE and RCODE on identical operands.  Take into account the
+   possibility of trapping if HONOR_NANS is nonzero, and return -1
+   if this makes the transformation invalid.  */
+enum comparison_code
+combine_comparisons (enum tree_code lcode, enum tree_code rcode,
+		     enum tree_code code, bool honor_nans)
+{
+  int lcompcode = comparison_to_compcode (lcode);
+  int rcompcode = comparison_to_compcode (rcode);
+  int compcode = (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR)
+                 ? lcompcode & rcompcode
+                 : lcompcode | rcompcode;
+
+  if (!honor_nans)
+    {
+      compcode &= ~COMPCODE_UNORD;
+      if (compcode == COMPCODE_LTGT)
+	return COMPCODE_NE;
+      if (compcode == COMPCODE_ORD)
+	return COMPCODE_TRUE;
+    }
+   else if (flag_trapping_math)
+     {
+	/* FIXME: Does LTGT trap?!? */
+	bool ltrap = lcompcode == COMPCODE_LT || compcode == COMPCODE_LE
+		    || compcode == COMPCODE_GT || compcode == COMPCODE_GE;
+	bool rtrap = rcompcode == COMPCODE_LT || compcode == COMPCODE_LE
+		    || compcode == COMPCODE_GT || compcode == COMPCODE_GE;
+	bool trap = compcode == COMPCODE_LT || compcode == COMPCODE_LE
+		    || compcode == COMPCODE_GT || compcode == COMPCODE_GE;
+	 
+        /* If the comparison was short-circuited, and only the RHS
+	   trapped, we may now generate a spurious trap.  */
+	if ((code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
+	    && !ltrap && rtrap)
+	  return COMPCODE_INVALID;
+
+	/* If we changed whether we trap, we lose.  */
+	if ((ltrap || rtrap) != trap)
+	  return COMPCODE_INVALID;
+      }
+
+  return compcode;
+}
+
 /* Return nonzero if CODE is a tree code that represents a truth value.  */
 
 static int
@@ -2699,20 +2811,18 @@ invert_truthvalue (tree arg)
     {
       if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
 	  && !flag_unsafe_math_optimizations
-	  && code != NE_EXPR
-	  && code != EQ_EXPR)
-	return build1 (TRUTH_NOT_EXPR, type, arg);
-      else if (code == UNORDERED_EXPR
-	       || code == ORDERED_EXPR
-	       || code == UNEQ_EXPR
-	       || code == UNLT_EXPR
-	       || code == UNLE_EXPR
-	       || code == UNGT_EXPR
-	       || code == UNGE_EXPR)
+	  && code != ORDERED_EXPR && code != UNORDERED_EXPR
+	  && code != NE_EXPR && code != EQ_EXPR)
 	return build1 (TRUTH_NOT_EXPR, type, arg);
       else
-	return build2 (invert_tree_comparison (code), type,
-		       TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
+	{
+	  code = invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (type)));
+	  if (code == ERROR_MARK)
+	    return build1 (TRUTH_NOT_EXPR, type, arg);
+	  else
+	    return build2 (code, type,
+			   TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
+	}
     }
 
   switch (code)
@@ -4011,9 +4121,6 @@ fold_truthop (enum tree_code code, tree 
   if (TREE_CODE_CLASS (lcode) != '<' || TREE_CODE_CLASS (rcode) != '<')
     return 0;
 
-  code = ((code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR)
-	  ? TRUTH_AND_EXPR : TRUTH_OR_EXPR);
-
   ll_arg = TREE_OPERAND (lhs, 0);
   lr_arg = TREE_OPERAND (lhs, 1);
   rl_arg = TREE_OPERAND (rhs, 0);
@@ -4021,46 +4128,34 @@ fold_truthop (enum tree_code code, tree 
 
   /* Simplify (x<y) && (x==y) into (x<=y) and related optimizations.  */
   if (simple_operand_p (ll_arg)
-      && simple_operand_p (lr_arg)
-      && !FLOAT_TYPE_P (TREE_TYPE (ll_arg)))
+      && simple_operand_p (lr_arg))
     {
       int compcode;
-
       if (operand_equal_p (ll_arg, rl_arg, 0)
           && operand_equal_p (lr_arg, rr_arg, 0))
-        {
-          int lcompcode, rcompcode;
-
-          lcompcode = comparison_to_compcode (lcode);
-          rcompcode = comparison_to_compcode (rcode);
-          compcode = (code == TRUTH_AND_EXPR)
-                     ? lcompcode & rcompcode
-                     : lcompcode | rcompcode;
-        }
+        compcode =
+	  combine_comparisons (lcode, rcode, code,
+			       HONOR_NANS (TYPE_MODE (TREE_TYPE (ll_arg))));
       else if (operand_equal_p (ll_arg, rr_arg, 0)
                && operand_equal_p (lr_arg, rl_arg, 0))
-        {
-          int lcompcode, rcompcode;
-
-          rcode = swap_tree_comparison (rcode);
-          lcompcode = comparison_to_compcode (lcode);
-          rcompcode = comparison_to_compcode (rcode);
-          compcode = (code == TRUTH_AND_EXPR)
-                     ? lcompcode & rcompcode
-                     : lcompcode | rcompcode;
-        }
+        compcode =
+	  combine_comparisons (lcode, swap_tree_comparison (rcode), code,
+			       HONOR_NANS (TYPE_MODE (TREE_TYPE (ll_arg))));
       else
-	compcode = -1;
+	compcode = COMPCODE_INVALID;
 
       if (compcode == COMPCODE_TRUE)
 	return fold_convert (truth_type, integer_one_node);
       else if (compcode == COMPCODE_FALSE)
 	return fold_convert (truth_type, integer_zero_node);
-      else if (compcode != -1)
+      else if (compcode != COMPCODE_INVALID)
 	return build2 (compcode_to_comparison (compcode),
 		       truth_type, ll_arg, lr_arg);
     }
 
+  code = ((code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR)
+	  ? TRUTH_AND_EXPR : TRUTH_OR_EXPR);
+
   /* If the RHS can be evaluated unconditionally and its operands are
      simple, it wins to evaluate the RHS unconditionally on machines
      with expensive branches.  In this case, this isn't a comparison
@@ -9856,7 +9951,7 @@ fold_relational_const (enum tree_code co
   if (code == NE_EXPR || code == GE_EXPR)
     {
       invert = 1;
-      code = invert_tree_comparison (code);
+      code = invert_tree_comparison (code, false);
     }
 
   /* Compute a result for LT or EQ if args permit;
Index: predict.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/predict.c,v
retrieving revision 1.104
diff -u -p -r1.104 predict.c
--- predict.c	13 May 2004 06:39:44 -0000	1.104
+++ predict.c	26 May 2004 14:31:12 -0000
@@ -865,6 +865,7 @@ tree_predict_by_opcode (basic_block bb)
 	break;
 
       case NE_EXPR:
+      case LTGT_EXPR:
 	/* Floating point comparisons appears to behave in a very
 	   unpredictable way because of special role of = tests in
 	   FP code.  */
Index: real.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/real.c,v
retrieving revision 1.141
diff -u -p -r1.141 real.c
--- real.c	22 Mar 2004 00:40:44 -0000	1.141
+++ real.c	26 May 2004 14:31:12 -0000
@@ -1080,6 +1080,8 @@ real_compare (int icode, const REAL_VALU
       return do_compare (op0, op1, 1) >= 0;
     case UNEQ_EXPR:
       return do_compare (op0, op1, 0) == 0;
+    case LTGT_EXPR:
+      return do_compare (op0, op1, 0) != 0;
 
     default:
       abort ();
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.3
diff -u -p -r2.3 tree-cfg.c
--- tree-cfg.c	19 May 2004 19:30:27 -0000	2.3
+++ tree-cfg.c	26 May 2004 14:31:13 -0000
@@ -3097,6 +3097,7 @@ verify_expr (tree *tp, int *walk_subtree
     case UNGT_EXPR:
     case UNGE_EXPR:
     case UNEQ_EXPR:
+    case LTGT_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.102
diff -u -p -r1.102 tree-inline.c
--- tree-inline.c	15 May 2004 23:07:51 -0000	1.102
+++ tree-inline.c	26 May 2004 14:31:14 -0000
@@ -1324,6 +1324,7 @@ estimate_num_insns_1 (tree *tp, int *wal
     case UNGT_EXPR:
     case UNGE_EXPR:
     case UNEQ_EXPR:
+    case LTGT_EXPR:
 
     case CONVERT_EXPR:
 
Index: tree-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-pretty-print.c,v
retrieving revision 2.2
diff -u -p -r2.2 tree-pretty-print.c
--- tree-pretty-print.c	15 May 2004 23:07:52 -0000	2.2
+++ tree-pretty-print.c	26 May 2004 14:31:14 -0000
@@ -905,6 +905,9 @@ dump_generic_node (pretty_printer *buffe
     case UNGT_EXPR:
     case UNGE_EXPR:
     case UNEQ_EXPR:
+    case LTGT_EXPR:
+    case ORDERED_EXPR:
+    case UNORDERED_EXPR:
       {
 	const char *op = op_symbol (node);
 	op0 = TREE_OPERAND (node, 0);
@@ -999,14 +1002,6 @@ dump_generic_node (pretty_printer *buffe
       pp_character (buffer, '>');
       break;
 
-    case UNORDERED_EXPR:
-      NIY;
-      break;
-
-    case ORDERED_EXPR:
-      NIY;
-      break;
-
     case IN_EXPR:
       NIY;
       break;
@@ -1681,6 +1676,14 @@ op_prio (tree op)
     case NE_EXPR:
       return 9;
 
+    case UNLT_EXPR:
+    case UNLE_EXPR:
+    case UNGT_EXPR:
+    case UNGE_EXPR:
+    case UNEQ_EXPR:
+    case LTGT_EXPR:
+    case ORDERED_EXPR:
+    case UNORDERED_EXPR:
     case LT_EXPR:
     case LE_EXPR:
     case GT_EXPR:
@@ -1786,28 +1789,41 @@ op_symbol (tree op)
     case BIT_AND_EXPR:
       return "&";
 
+    case ORDERED_EXPR:
+      return "ord";
+    case UNORDERED_EXPR:
+      return "unord";
+
     case EQ_EXPR:
-    case UNEQ_EXPR:
       return "==";
+    case UNEQ_EXPR:
+      return "u==";
 
     case NE_EXPR:
       return "!=";
 
     case LT_EXPR:
-    case UNLT_EXPR:
       return "<";
+    case UNLT_EXPR:
+      return "u<";
 
     case LE_EXPR:
-    case UNLE_EXPR:
       return "<=";
+    case UNLE_EXPR:
+      return "u<=";
 
     case GT_EXPR:
-    case UNGT_EXPR:
       return ">";
+    case UNGT_EXPR:
+      return "u>";
 
     case GE_EXPR:
-    case UNGE_EXPR:
       return ">=";
+    case UNGE_EXPR:
+      return "u>=";
+
+    case LTGT_EXPR:
+      return "<>";
 
     case LSHIFT_EXPR:
       return "<<";
Index: tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.def,v
retrieving revision 1.76
diff -u -p -r1.76 tree.def
--- tree.def	14 May 2004 02:32:58 -0000	1.76
+++ tree.def	26 May 2004 14:31:14 -0000
@@ -681,6 +681,9 @@ DEFTREECODE (UNGT_EXPR, "ungt_expr", '<'
 DEFTREECODE (UNGE_EXPR, "unge_expr", '<', 2)
 DEFTREECODE (UNEQ_EXPR, "uneq_expr", '<', 2)
 
+/* This is the reverse of uneq_expr.  */
+DEFTREECODE (LTGT_EXPR, "ltgt_expr", '<', 2)
+
 /* Operations for Pascal sets.  Not used now.  */
 DEFTREECODE (IN_EXPR, "in_expr", '2', 2)
 DEFTREECODE (SET_LE_EXPR, "set_le_expr", '<', 2)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]