diff options
author | Roger Sayle <roger@eyesopen.com> | 2006-04-17 02:38:50 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2006-04-17 02:38:50 +0000 |
commit | 726ac11ebd7552453d39f084cf9d05d2bbc91b58 (patch) | |
tree | 2246af5954be107f6f28cf1fb9e1c7dd4cd48008 /gcc | |
parent | 27b996417598f927b5d40c4477a917c898848e0e (diff) | |
download | gcc-726ac11ebd7552453d39f084cf9d05d2bbc91b58.zip gcc-726ac11ebd7552453d39f084cf9d05d2bbc91b58.tar.gz gcc-726ac11ebd7552453d39f084cf9d05d2bbc91b58.tar.bz2 |
re PR target/26961 (ICE simplify_subreg:3813)
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.
* gcc.dg/fold-cond-1.c: New test case.
* gcc.dg/pr26961-1.c: Likewise.
From-SVN: r113001
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/fold-cond-1.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr26961-1.c | 8 |
5 files changed, 60 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2afcfc1..90f18a9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index ddc56f6..deb568cd 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 173395e..32e2d11 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..e9212d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-cond-1.c @@ -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 index 0000000..56907d8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr26961-1.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +long long foo(int i, int j) +{ + return i ? (long long)(!j) : 0; +} + |