OSDN Git Service

PR middle-end/40747
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Jul 2009 10:17:54 +0000 (10:17 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Jul 2009 10:17:54 +0000 (10:17 +0000)
* fold-const.c (fold_cond_expr_with_comparison): When folding
< and <= to MIN, make sure the MIN uses the same type as the
comparison's operands.

* gcc.c-torture/execute/pr40747.c: New test.

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

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr40747.c [new file with mode: 0644]

index 8ae44d8..d68d157 100644 (file)
@@ -1,3 +1,10 @@
+2009-07-15  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/40747
+       * fold-const.c (fold_cond_expr_with_comparison): When folding
+       < and <= to MIN, make sure the MIN uses the same type as the
+       comparison's operands.
+
 2009-07-15  Richard Earnshaw  <rearnsha@arm.com>
 
        * arm.md (ior_xor): New code iterator.
index f3e0614..eba8690 100644 (file)
@@ -5310,31 +5310,35 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
        return fold_build3 (COND_EXPR, type, arg0, arg1, arg2);
 
       case LT_EXPR:
-       /* If C1 is C2 + 1, this is min(A, C2).  */
+       /* If C1 is C2 + 1, this is min(A, C2), but use ARG00's type for
+          MIN_EXPR, to preserve the signedness of the comparison.  */
        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 (MIN_EXPR,
-                                                  type,
-                                                  fold_convert (type, arg1),
-                                                  arg2));
+         {
+           tem = fold_build2 (MIN_EXPR, TREE_TYPE (arg00), arg00,
+                              fold_convert (TREE_TYPE (arg00), arg2));
+           return pedantic_non_lvalue (fold_convert (type, tem));
+         }
        break;
 
       case LE_EXPR:
-       /* If C1 is C2 - 1, this is min(A, C2).  */
+       /* If C1 is C2 - 1, this is min(A, C2), with the same care
+          as above.  */
        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 (MIN_EXPR,
-                                                  type,
-                                                  fold_convert (type, arg1),
-                                                  arg2));
+         {
+           tem = fold_build2 (MIN_EXPR, TREE_TYPE (arg00), arg00,
+                              fold_convert (TREE_TYPE (arg00), arg2));
+           return pedantic_non_lvalue (fold_convert (type, tem));
+         }
        break;
 
       case GT_EXPR:
@@ -5346,11 +5350,11 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
                                const_binop (MINUS_EXPR, arg2,
                                             build_int_cst (type, 1), 0),
                                OEP_ONLY_CONST))
-         return pedantic_non_lvalue (fold_convert (type,
-                                     fold_build2 (MAX_EXPR, TREE_TYPE (arg00),
-                                                  arg00,
-                                                  fold_convert (TREE_TYPE (arg00),
-                                                                arg2))));
+         {
+           tem = fold_build2 (MAX_EXPR, TREE_TYPE (arg00), arg00,
+                              fold_convert (TREE_TYPE (arg00), arg2));
+           return pedantic_non_lvalue (fold_convert (type, tem));
+         }
        break;
 
       case GE_EXPR:
@@ -5361,11 +5365,11 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
                                const_binop (PLUS_EXPR, arg2,
                                             build_int_cst (type, 1), 0),
                                OEP_ONLY_CONST))
-         return pedantic_non_lvalue (fold_convert (type,
-                                     fold_build2 (MAX_EXPR, TREE_TYPE (arg00),
-                                                  arg00,
-                                                  fold_convert (TREE_TYPE (arg00),
-                                                                arg2))));
+         {
+           tem = fold_build2 (MAX_EXPR, TREE_TYPE (arg00), arg00,
+                              fold_convert (TREE_TYPE (arg00), arg2));
+           return pedantic_non_lvalue (fold_convert (type, tem));
+         }
        break;
       case NE_EXPR:
        break;
index e58a25b..6083654 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-15  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/40747
+       * gcc.c-torture/execute/pr40747.c: New test.
+
 2009-07-15  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/40753
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr40747.c b/gcc/testsuite/gcc.c-torture/execute/pr40747.c
new file mode 100644 (file)
index 0000000..1c75be3
--- /dev/null
@@ -0,0 +1,22 @@
+/* PR middle-end/40747 */
+
+extern void abort (void);
+
+int
+foo (int i)
+{
+  return (i < 4 && i >= 0) ? i : 4;
+}
+
+int
+main ()
+{
+  if (foo (-1) != 4) abort ();
+  if (foo (0) != 0) abort ();
+  if (foo (1) != 1) abort ();
+  if (foo (2) != 2) abort ();
+  if (foo (3) != 3) abort ();
+  if (foo (4) != 4) abort ();
+  if (foo (5) != 4) abort ();
+  return 0;
+}