OSDN Git Service

2009-04-24 Paolo Bonzini <bonzini@gnu.org>
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Apr 2009 10:29:18 +0000 (10:29 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Apr 2009 10:29:18 +0000 (10:29 +0000)
PR middle-end/39867
* fold-const.c (fold_cond_expr_with_comparison): When folding
> and >= to MAX, make sure the MAX uses the same type as the
comparison operands.

testsuite:
2009-04-24  Paolo Bonzini  <bonzini@gnu.org>

PR middle-end/39867
* gcc.dg/pr39867.c: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146695 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr39867.c [new file with mode: 0644]

index 7ab7374..baa9d2c 100644 (file)
@@ -1,3 +1,10 @@
+2009-04-24  Paolo Bonzini  <bonzini@gnu.org>
+
+       PR middle-end/39867
+       * fold-const.c (fold_cond_expr_with_comparison): When folding
+       > and >= to MAX, make sure the MAX uses the same type as the
+       comparison's operands.
+
 2009-04-24  Nick Clifton  <nickc@redhat.com>
 
        * config/frv/frv.c (frv_frame_access): Do not use reg+reg
index f0ff5b6..9a2687a 100644 (file)
@@ -5337,31 +5337,34 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
        break;
 
       case GT_EXPR:
-       /* If C1 is C2 - 1, this is max(A, C2).  */
+       /* If C1 is C2 - 1, this is max(A, C2), but use ARG00's type for
+          MAX_EXPR, to preserve the signedness of the comparison.  */
        if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
                               OEP_ONLY_CONST)
            && operand_equal_p (arg01,
                                const_binop (MINUS_EXPR, arg2,
                                             build_int_cst (type, 1), 0),
                                OEP_ONLY_CONST))
-         return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
-                                                  type,
-                                                  fold_convert (type, arg1),
-                                                  arg2));
+         return pedantic_non_lvalue (fold_convert (type,
+                                     fold_build2 (MAX_EXPR, TREE_TYPE (arg00),
+                                                  arg00,
+                                                  fold_convert (TREE_TYPE (arg00),
+                                                                arg2))));
        break;
 
       case GE_EXPR:
-       /* If C1 is C2 + 1, this is max(A, C2).  */
+       /* If C1 is C2 + 1, this is max(A, C2), with the same care as above.  */
        if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
                               OEP_ONLY_CONST)
            && operand_equal_p (arg01,
                                const_binop (PLUS_EXPR, arg2,
                                             build_int_cst (type, 1), 0),
                                OEP_ONLY_CONST))
-         return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
-                                                  type,
-                                                  fold_convert (type, arg1),
-                                                  arg2));
+         return pedantic_non_lvalue (fold_convert (type,
+                                     fold_build2 (MAX_EXPR, TREE_TYPE (arg00),
+                                                  arg00,
+                                                  fold_convert (TREE_TYPE (arg00),
+                                                                arg2))));
        break;
       case NE_EXPR:
        break;
index 9f18666..7fd0f1f 100644 (file)
@@ -1,3 +1,8 @@
+2009-04-24  Paolo Bonzini  <bonzini@gnu.org>
+
+       PR middle-end/39867
+       * gcc.dg/pr39867.c: New.
+
 2009-04-24  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/39861
diff --git a/gcc/testsuite/gcc.dg/pr39867.c b/gcc/testsuite/gcc.dg/pr39867.c
new file mode 100644 (file)
index 0000000..cb79724
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+
+int main (void)
+{
+  int exp = -1;
+  /* Wrong folding of the LHS to an unsigned MAX leads to 4294967295 != 2.  */
+  if ((exp < 2 ? 2U : (unsigned int) exp) != 2)
+    link_error ();
+  return 0;
+}
+