aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-05-14 08:26:23 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2013-05-14 08:26:23 +0200
commitf778dd4dbb61b05f02d2307d22e0cbd4bcecfc7a (patch)
treebf9381f02ef3766d9290071d7a280107017ebefd /gcc
parentbad4df9b766a375b51c37403f1d6015b4db19c56 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/expr.c29
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57251.c12
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
diff --git a/gcc/expr.c b/gcc/expr.c
index 5663408..0149740 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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;
+}