summaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-11-22 10:57:28 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-11-22 10:57:28 +0100
commita2998ed1dc4389e2d648ba376f1eca2c165a2717 (patch)
treee74efc9fd718473642ee90a0a64c09bac23f4832 /gcc/optabs.c
parent0a770b5907cdb70709356fbbfe5c570010b0b936 (diff)
re PR middle-end/82875 (ICE at -Os on valid code on x86_64-linux-gnu: in find_widening_optab_handler_and_mode, at optabs-query.c:414)
PR middle-end/82875 * optabs.c (expand_doubleword_mult, expand_binop): Before calling expand_binop with *mul_widen_optab, make sure at least one of the operands doesn't have VOIDmode. * gcc.dg/pr82875.c: New test. * gcc.c-torture/compile/pr82875.c: New test. From-SVN: r255050
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 847b801d288..518ce7a972c 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -861,6 +861,11 @@ expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
if (target && !REG_P (target))
target = NULL_RTX;
+ /* *_widen_optab needs to determine operand mode, make sure at least
+ one operand has non-VOID mode. */
+ if (GET_MODE (op0_low) == VOIDmode && GET_MODE (op1_low) == VOIDmode)
+ op0_low = force_reg (word_mode, op0_low);
+
if (umulp)
product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
target, 1, OPTAB_DIRECT);
@@ -1199,6 +1204,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
: smul_widen_optab),
wider_mode, mode) != CODE_FOR_nothing))
{
+ /* *_widen_optab needs to determine operand mode, make sure at least
+ one operand has non-VOID mode. */
+ if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
+ op0 = force_reg (mode, op0);
temp = expand_binop (wider_mode,
unsignedp ? umul_widen_optab : smul_widen_optab,
op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);