diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-05-14 08:26:23 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-05-14 08:26:23 +0200 |
commit | f778dd4dbb61b05f02d2307d22e0cbd4bcecfc7a (patch) | |
tree | bf9381f02ef3766d9290071d7a280107017ebefd /gcc | |
parent | bad4df9b766a375b51c37403f1d6015b4db19c56 (diff) | |
download | gcc-f778dd4dbb61b05f02d2307d22e0cbd4bcecfc7a.zip gcc-f778dd4dbb61b05f02d2307d22e0cbd4bcecfc7a.tar.gz gcc-f778dd4dbb61b05f02d2307d22e0cbd4bcecfc7a.tar.bz2 |
re PR tree-optimization/57251 (ICE in optab_handler, at optabs.h:258)
PR middle-end/57251
* expr.c (expand_expr_real_2) <case WIDEN_MULT_EXPR>: Handle
the case when both op0 and op1 have VOIDmode.
* gcc.dg/torture/pr57251.c: New test.
From-SVN: r198860
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expr.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr57251.c | 12 |
4 files changed, 51 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a6c09bc..ea7c39b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-05-14 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/57251 + * expr.c (expand_expr_real_2) <case WIDEN_MULT_EXPR>: Handle + the case when both op0 and op1 have VOIDmode. + 2013-05-14 Kaushik Phatak <kaushik.phatak@kpitcummins.com> * config/rl78/rl78.md(mulsi3_g13): Add additional 'nop' required @@ -8390,6 +8390,15 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, else expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0, EXPAND_NORMAL); + /* op0 and op1 might still be constant, despite the above + != INTEGER_CST check. Handle it. */ + if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode) + { + op0 = convert_modes (innermode, mode, op0, true); + op1 = convert_modes (innermode, mode, op1, false); + return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, + target, unsignedp)); + } goto binop3; } } @@ -8412,6 +8421,19 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, { expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); + /* op0 and op1 might still be constant, despite the above + != INTEGER_CST check. Handle it. */ + if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode) + { + widen_mult_const: + op0 = convert_modes (innermode, mode, op0, zextend_p); + op1 + = convert_modes (innermode, mode, op1, + TYPE_UNSIGNED (TREE_TYPE (treeop1))); + return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, + target, + unsignedp)); + } temp = expand_widening_mult (mode, op0, op1, target, unsignedp, this_optab); return REDUCE_BIT_FIELD (temp); @@ -8424,9 +8446,14 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, op0 = expand_normal (treeop0); if (TREE_CODE (treeop1) == INTEGER_CST) op1 = convert_modes (innermode, mode, - expand_normal (treeop1), unsignedp); + expand_normal (treeop1), + TYPE_UNSIGNED (TREE_TYPE (treeop1))); else op1 = expand_normal (treeop1); + /* op0 and op1 might still be constant, despite the above + != INTEGER_CST check. Handle it. */ + if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode) + goto widen_mult_const; temp = expand_binop (mode, other_optab, op0, op1, target, unsignedp, OPTAB_LIB_WIDEN); hipart = gen_highpart (innermode, temp); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6c8691f..24e9f24 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-05-14 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/57251 + * gcc.dg/torture/pr57251.c: New test. + 2013-05-13 Uros Bizjak <ubizjak@gmail.com> PR target/57264 diff --git a/gcc/testsuite/gcc.dg/torture/pr57251.c b/gcc/testsuite/gcc.dg/torture/pr57251.c new file mode 100644 index 0000000..2fe268c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57251.c @@ -0,0 +1,12 @@ +/* PR middle-end/57251 */ +/* { dg-do compile } */ +/* { dg-options "-ftracer" } */ + +short a, b; +int +f (void) +{ + long long i = 2; + a ? f () ? : 0 : b--; + b &= i *= a |= 0; +} |