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]

Re: [PATCH] Document a bunch of expression tree codes


	NOT_EXPR (UNORDERED_EXPR (x, y)) => ORDERED_EXPR (x, y)
	NOT_EXPR (ORDERED_EXPR (x, y)) => UNORDERED_EXPR (x, y)
	UNORDERED (x, x) => isnan (x)
	ORDERED (x, x) => NOT_EXPR (isnan (x))
	isnan (x) || isnan (y) => UNORDERED (x, y)
	!isnan (x) && !isnan (y) => ORDERED (x, y)

I think so. I'm sure about the last two; from there, the rest are simple algebraic manipulations.


And if -fno-trapping-math,

NOT_EXPR (UNLT_EXPR (x, y)) => GE_EXPR (x, y)
>
And if -fno-trapping-math and HONOR_NANS (mode),

NOT_EXPR (GE_EXPR (x, y)) => UNLT_EXPR (x, y)

I also think so. Both of these actually require HONOR_NANS, otherwise UNLT_EXPR would not be produced, would it?


Would something like the attached patch be acceptable if the regtests pass? Would additional regtests be necessary?

Paolo

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

	* 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.
	(op_symbol): Print unordered comparison differently.
	* tree.def (LTGT_EXPR): New '<' tree code.
	* fold-const.c (invert_tree_comparison): Add HONOR_NANS
	parameter.
	(invert_truthvalue): Let invert_tree_comparison decide
	whether it is valid to fold the comparison.
	(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 -p -u -r1.501 c-common.c
--- c-common.c	22 May 2004 18:16:38 -0000	1.501
+++ c-common.c	26 May 2004 07:58:38 -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 -p -u -r1.304 c-typeck.c
--- c-typeck.c	14 May 2004 02:32:55 -0000	1.304
+++ c-typeck.c	26 May 2004 07:58:39 -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 -p -u -r1.16 dojump.c
--- dojump.c	29 Apr 2004 07:50:55 -0000	1.16
+++ dojump.c	26 May 2004 07:58:39 -0000
@@ -525,7 +525,7 @@ do_jump (tree exp, rtx if_false_label, r
 
     {
       enum rtx_code rcode1;
-      enum tree_code tcode2;
+      enum tree_code tcode1 = UNORDERED_EXPR, tcode2;
 
       case UNLT_EXPR:
         rcode1 = UNLT;
@@ -547,6 +547,11 @@ do_jump (tree exp, rtx if_false_label, r
         rcode1 = UNEQ;
         tcode2 = EQ_EXPR;
         goto unordered_bcc;
+      case LTGT_EXPR:
+        rcode1 = LTGT;
+        tcode1 = LT_EXPR;
+        tcode2 = GT_EXPR;
+        goto unordered_bcc;
 
       unordered_bcc:
         mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
@@ -560,8 +565,8 @@ 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);
             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 -p -u -r1.647 expr.c
--- expr.c	19 May 2004 06:26:21 -0000	1.647
+++ expr.c	26 May 2004 07:58:41 -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 -p -u -r1.382 fold-const.c
--- fold-const.c	24 May 2004 03:02:44 -0000	1.382
+++ fold-const.c	26 May 2004 07:58:43 -0000
@@ -69,7 +69,7 @@ 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);
@@ -2057,11 +2057,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 +2073,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 ();
     }
@@ -2702,17 +2722,15 @@ invert_truthvalue (tree arg)
 	  && 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)
-	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)
@@ -9856,7 +9874,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 -p -u -r1.104 predict.c
--- predict.c	13 May 2004 06:39:44 -0000	1.104
+++ predict.c	26 May 2004 07:58:44 -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 -p -u -r1.141 real.c
--- real.c	22 Mar 2004 00:40:44 -0000	1.141
+++ real.c	26 May 2004 07:58:44 -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 -p -u -r2.3 tree-cfg.c
--- tree-cfg.c	19 May 2004 19:30:27 -0000	2.3
+++ tree-cfg.c	26 May 2004 07:58:45 -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 -p -u -r1.102 tree-inline.c
--- tree-inline.c	15 May 2004 23:07:51 -0000	1.102
+++ tree-inline.c	26 May 2004 07:58:45 -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 -p -u -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 07:58:45 -0000
@@ -905,6 +905,7 @@ dump_generic_node (pretty_printer *buffe
     case UNGT_EXPR:
     case UNGE_EXPR:
     case UNEQ_EXPR:
+    case LTGT_EXPR:
       {
 	const char *op = op_symbol (node);
 	op0 = TREE_OPERAND (node, 0);
@@ -1787,27 +1788,35 @@ op_symbol (tree op)
       return "&";
 
     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 -p -u -r1.76 tree.def
--- tree.def	14 May 2004 02:32:58 -0000	1.76
+++ tree.def	26 May 2004 07:58:46 -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]