OSDN Git Service

PR target/26961
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 17 Apr 2006 02:38:50 +0000 (02:38 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 17 Apr 2006 02:38:50 +0000 (02:38 +0000)
* fold-const.c (fold_ternary): When converting "A ? B : C" into either
"A op B" or "A op C", we may need to convert A to the type of B and C.

* gcc.dg/fold-cond-1.c: New test case.
* gcc.dg/pr26961-1.c: Likewise.

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

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

index 2afcfc1..90f18a9 100644 (file)
@@ -1,3 +1,9 @@
+2006-04-16  Roger Sayle  <roger@eyesopen.com>
+
+       PR target/26961
+       * fold-const.c (fold_ternary): When converting "A ? B : C" into either
+       "A op B" or "A op C", we may need to convert A to the type of B and C.
+
 2006-04-16  Adam Nemet  <anemet@caviumnetworks.com>
 
        * target.h (struct gcc_target): Add mode_rep_extended.
index ddc56f6..deb568c 100644 (file)
@@ -11073,7 +11073,9 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2)
       if (integer_zerop (op2)
          && truth_value_p (TREE_CODE (arg0))
          && truth_value_p (TREE_CODE (arg1)))
-       return fold_build2 (TRUTH_ANDIF_EXPR, type, arg0, arg1);
+       return fold_build2 (TRUTH_ANDIF_EXPR, type,
+                           fold_convert (type, arg0),
+                           arg1);
 
       /* Convert A ? B : 1 into !A || B if A and B are truth values.  */
       if (integer_onep (op2)
@@ -11083,7 +11085,9 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2)
          /* Only perform transformation if ARG0 is easily inverted.  */
          tem = invert_truthvalue (arg0);
          if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
-           return fold_build2 (TRUTH_ORIF_EXPR, type, tem, arg1);
+           return fold_build2 (TRUTH_ORIF_EXPR, type,
+                               fold_convert (type, tem),
+                               arg1);
        }
 
       /* Convert A ? 0 : B into !A && B if A and B are truth values.  */
@@ -11094,14 +11098,18 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2)
          /* Only perform transformation if ARG0 is easily inverted.  */
          tem = invert_truthvalue (arg0);
          if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
-           return fold_build2 (TRUTH_ANDIF_EXPR, type, tem, op2);
+           return fold_build2 (TRUTH_ANDIF_EXPR, type,
+                               fold_convert (type, tem),
+                               op2);
        }
 
       /* Convert A ? 1 : B into A || B if A and B are truth values.  */
       if (integer_onep (arg1)
          && truth_value_p (TREE_CODE (arg0))
          && truth_value_p (TREE_CODE (op2)))
-       return fold_build2 (TRUTH_ORIF_EXPR, type, arg0, op2);
+       return fold_build2 (TRUTH_ORIF_EXPR, type,
+                           fold_convert (type, arg0),
+                           op2);
 
       return NULL_TREE;
 
index 173395e..32e2d11 100644 (file)
@@ -1,3 +1,9 @@
+2006-04-16  Roger Sayle  <roger@eyesopen.com>
+
+       PR target/26961
+       * gcc.dg/fold-cond-1.c: New test case.
+       * gcc.dg/pr26961-1.c: Likewise.
+
 2006-04-16  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR libgfortran/27138
diff --git a/gcc/testsuite/gcc.dg/fold-cond-1.c b/gcc/testsuite/gcc.dg/fold-cond-1.c
new file mode 100644 (file)
index 0000000..e9212d1
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+
+_Bool test1(int a, int b)
+{
+  return a ? b : 0;
+}
+
+_Bool test2(int c, int d)
+{
+  return c ? d : 1;
+}
+
+_Bool test3(int e, int f)
+{
+  return e ? 0 : f;
+}
+
+_Bool test4(int g, int h)
+{
+  return g ? 1 : h;
+}
+
+/* { dg-final { scan-tree-dump-times "a != 0 \&\& b != 0" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "c == 0 \\|\\| d != 0" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "e == 0 \&\& f != 0" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "\\(g \\| h\\) != 0" 1 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
diff --git a/gcc/testsuite/gcc.dg/pr26961-1.c b/gcc/testsuite/gcc.dg/pr26961-1.c
new file mode 100644 (file)
index 0000000..56907d8
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+long long foo(int i, int j)
+{
+  return i ? (long long)(!j) : 0;
+}
+