This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Committed] PR17236: Improve double-word multiply RTL expansion
- From: Roger Sayle <roger at eyesopen dot com>
- To: Ulrich Weigand <uweigand at de dot ibm dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 15 Mar 2005 15:49:24 -0700 (MST)
- Subject: Re: [Committed] PR17236: Improve double-word multiply RTL expansion
On Tue, 15 Mar 2005, Ulrich Weigand wrote:
> This causes bootstrap failure on s390-ibm-linux because the stage1 cc1
> miscompiles the 'divide' routine in tree-ssa-loop-ivopts.c:
> It looks the cause for the miscompile is that
>
> > + /* ??? This could be done with emit_store_flag where available. */
> > + temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
> > + NULL_RTX, 1, methods);
> > + if (temp)
> > + op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
> > + op0_high, 0, OPTAB_DIRECT);
>
> this clobbers the original input 'op0_high' which might be needed
> later on. Likewise op1_high later on.
>
> While you write:
> > + /* OP0_HIGH should now be dead. */
>
> this really only means op0_high is not needed any more to perform
> *this* multiplication operation, but the variable may of course
> not be dead at the original source code level ...
Argh! Sorry. Could you see whether the following patch resolves the
bootstrap failure on s390-ibm-linux for you?
Sorry again for the inconvenience,
2005-03-15 Roger Sayle <roger@eyesopen.com>
* optabs.c (expand_doubleword_mult): Avoid clobbering op0 and
op1 whilst expanding the signed widenening multiply variant.
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.263
diff -c -3 -p -r1.263 optabs.c
*** optabs.c 15 Mar 2005 20:43:12 -0000 1.263
--- optabs.c 15 Mar 2005 22:46:10 -0000
*************** expand_doubleword_mult (enum machine_mod
*** 843,849 ****
NULL_RTX, 1, methods);
if (temp)
op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
! op0_high, 0, OPTAB_DIRECT);
else
{
temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
--- 843,849 ----
NULL_RTX, 1, methods);
if (temp)
op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
! NULL_RTX, 0, OPTAB_DIRECT);
else
{
temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
*************** expand_doubleword_mult (enum machine_mod
*** 851,857 ****
if (!temp)
return NULL_RTX;
op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
! op0_high, 0, OPTAB_DIRECT);
}
if (!op0_high)
--- 851,857 ----
if (!temp)
return NULL_RTX;
op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
! NULL_RTX, 0, OPTAB_DIRECT);
}
if (!op0_high)
*************** expand_doubleword_mult (enum machine_mod
*** 872,878 ****
NULL_RTX, 1, methods);
if (temp)
op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
! op1_high, 0, OPTAB_DIRECT);
else
{
temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
--- 872,878 ----
NULL_RTX, 1, methods);
if (temp)
op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
! NULL_RTX, 0, OPTAB_DIRECT);
else
{
temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
*************** expand_doubleword_mult (enum machine_mod
*** 880,886 ****
if (!temp)
return NULL_RTX;
op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
! op1_high, 0, OPTAB_DIRECT);
}
if (!op1_high)
--- 880,886 ----
if (!temp)
return NULL_RTX;
op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
! NULL_RTX, 0, OPTAB_DIRECT);
}
if (!op1_high)
Roger
--