This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch for gcc.dg/compare2.c "case 10"
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch for gcc.dg/compare2.c "case 10"
- From: Zack Weinberg <zack at wolery dot cumb dot org>
- Date: Thu, 1 Jun 2000 12:47:59 -0700
This patch gets rid of the spurious signed/unsigned warning for
unsigned > ({ signed; 23; });
The tree structure for the right-hand side looks like
<bind_expr
type <integer_type int>
body <rtl_expr type <integer_type int>
rtl 0 (insn) (insn) ...
rtl 1 (const_int 23)
>
block <...>>
so we just have to teach tree_expr_nonnegative_p to look inside
BIND_EXPRs and RTL_EXPRs for nonnegative constants. This is easy. It
is not good enough to fix case 12,
unsigned > ({ signed ? 12 : 24; }); /* simplified */
The RTL_EXPR for that one will do substantial work in the 'sequence'
slot and have a pseudo in the 'result' slot. It is theoretically
possible to deduce the relevant property from the RTL in the sequence,
but it would be a huge amount of effort, no doubt better applied to
functions as trees. I'm going to mark case 12 an expected failure.
I'm not 100% sure about the handling of CONST_DOUBLEs in
rtl_expr_nonnegative_p. I moved the functions to fold-const.c because
tree.c doesn't include rtl.h.
Bootstrapped i386-linux. There are a number of recent regressions in
libio and libstdc++ which I am 99% sure are not my fault.
zw
* tree.c (tree_expr_nonnegative_p): Move to...
* fold-const.c: ... here. Also handle BIND_EXPR and RTL_EXPR.
(rtl_expr_nonnegative_p): New.
* tree.h: Add prototype for rtl_expr_nonnegative_p.
===================================================================
Index: tree.h
--- tree.h 2000/05/31 20:53:37 1.175
+++ tree.h 2000/06/01 19:29:59
@@ -1878,7 +1878,8 @@ extern int host_integerp PARAMS ((tree,
extern HOST_WIDE_INT tree_low_cst PARAMS ((tree, int));
extern int tree_int_cst_msb PARAMS ((tree));
extern int tree_int_cst_sgn PARAMS ((tree));
-extern int tree_expr_nonnegative_p PARAMS ((tree));
+extern int tree_expr_nonnegative_p PARAMS ((tree));
+extern int rtl_expr_nonnegative_p PARAMS ((struct rtx_def *));
extern int index_type_equal PARAMS ((tree, tree));
extern tree get_inner_array_type PARAMS ((tree));
===================================================================
Index: fold-const.c
--- fold-const.c 2000/05/31 11:55:53 1.120
+++ fold-const.c 2000/06/01 19:30:00
@@ -7228,3 +7228,54 @@ multiple_of_p (type, top, bottom)
return 0;
}
}
+
+/* Return true if `t' is known to be non-negative. */
+
+int
+tree_expr_nonnegative_p (t)
+ tree t;
+{
+ switch (TREE_CODE (t))
+ {
+ case INTEGER_CST:
+ return tree_int_cst_sgn (t) >= 0;
+ case COND_EXPR:
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
+ && tree_expr_nonnegative_p (TREE_OPERAND (t, 2));
+ case BIND_EXPR:
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+ case RTL_EXPR:
+ return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t));
+
+ default:
+ /* We don't know sign of `t', so be safe and return false. */
+ return 0;
+ }
+}
+
+/* Return true if `r' is known to be non-negative.
+ Only handles constants at the moment. */
+
+int
+rtl_expr_nonnegative_p (r)
+ rtx r;
+{
+ switch (GET_CODE (r))
+ {
+ case CONST_INT:
+ return INTVAL (r) >= 0;
+
+ case CONST_DOUBLE:
+ if (GET_MODE_CLASS (GET_MODE (r)) == MODE_INT)
+ return XWINT (r, 3) >= 0; /* CONST_DOUBLE_HIGH not visible here. */
+ return 0;
+
+ case SYMBOL_REF:
+ case LABEL_REF:
+ /* These are always nonnegative. */
+ return 1;
+
+ default:
+ return 0;
+ }
+}
===================================================================
Index: tree.c
--- tree.c 2000/05/31 18:36:05 1.147
+++ tree.c 2000/06/01 19:30:01
@@ -4360,25 +4360,6 @@ tree_int_cst_sgn (t)
return 1;
}
-/* Return true if `t' is known to be non-negative. */
-
-int
-tree_expr_nonnegative_p (t)
- tree t;
-{
- switch (TREE_CODE (t))
- {
- case INTEGER_CST:
- return tree_int_cst_sgn (t) >= 0;
- case COND_EXPR:
- return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
- && tree_expr_nonnegative_p (TREE_OPERAND (t, 2));
- default:
- /* We don't know sign of `t', so be safe and return false. */
- return 0;
- }
-}
-
/* Compare two constructor-element-type constants. Return 1 if the lists
are known to be equal; otherwise return 0. */