This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR middle-end/12705: Overlapping complex expressions
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Paul Brook <paul at nowt dot org>
- Date: Wed, 22 Oct 2003 17:03:48 -0600 (MDT)
- Subject: [PATCH] PR middle-end/12705: Overlapping complex expressions
The following patch addresses PR middle-end/12705, which is a latent
bug in tree->RTL expansion. When expanding complex binary operations
we weren't testing whether the suggested target rtx overlapped with one
or other of the input operands. This can cause us to overwrite the
real or imaginary components of an operands before we've finished using
them. This problem was discovered using gfortran on the tree-ssa branch,
and diagnosed as a middle-end problem by RTH.
I considered using safe_from_p to identify when the operands and the
target actually overlap, but I wasn't immediately sure how well these
functions handled complex modes or whether I'd need to perform pairwise
safe_from_p tests on the individual real and imaginary components.
The safest and easiest solution is to just evaluate these expressions
into a new pseudo, which will get cleaned up by the RTL optimizers if
needed, but also exposes the intermediate values to CSE and GCSE.
Many thanks to Paul Brook for confirming this patch cures the problem.
The following patch has been tested against mainline on i686-pc-linux-gnu
with a complete "make bootstrap", all languages except treelang, and
regression tested with a top-level "make -k check" with no new failures.
As mentioned previously, this failure isn't reproducable with any of the
mainline front-ends, but I assume a gfortran testcase can be added to
the tree-ssa branch once this patch gets merged.
Ok for mainline?
2003-10-22 Roger Sayle <roger@eyesopen.com>
PR middle-end/12705
* optabs.c (expand_binop): When expanding complex operations
inline, always calculate result in a new temporary register.
Minor code clean-ups.
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.201
diff -c -3 -p -r1.201 optabs.c
*** optabs.c 20 Oct 2003 18:28:27 -0000 1.201
--- optabs.c 22 Oct 2003 02:38:08 -0000
*************** expand_binop (enum machine_mode mode, op
*** 1521,1544 ****
rtx real0 = 0, imag0 = 0;
rtx real1 = 0, imag1 = 0;
rtx realr, imagr, res;
! rtx seq;
! rtx equiv_value;
int ok = 0;
/* Find the correct mode for the real and imaginary parts. */
! enum machine_mode submode = GET_MODE_INNER(mode);
if (submode == BLKmode)
abort ();
- if (! target)
- target = gen_reg_rtx (mode);
-
start_sequence ();
- realr = gen_realpart (submode, target);
- imagr = gen_imagpart (submode, target);
-
if (GET_MODE (op0) == mode)
{
real0 = gen_realpart (submode, op0);
--- 1521,1537 ----
rtx real0 = 0, imag0 = 0;
rtx real1 = 0, imag1 = 0;
rtx realr, imagr, res;
! rtx seq, result;
int ok = 0;
/* Find the correct mode for the real and imaginary parts. */
! enum machine_mode submode = GET_MODE_INNER (mode);
if (submode == BLKmode)
abort ();
start_sequence ();
if (GET_MODE (op0) == mode)
{
real0 = gen_realpart (submode, op0);
*************** expand_binop (enum machine_mode mode, op
*** 1558,1563 ****
--- 1551,1560 ----
if (real0 == 0 || real1 == 0 || ! (imag0 != 0 || imag1 != 0))
abort ();
+ result = gen_reg_rtx (mode);
+ realr = gen_realpart (submode, result);
+ imagr = gen_imagpart (submode, result);
+
switch (binoptab->code)
{
case PLUS:
*************** expand_binop (enum machine_mode mode, op
*** 1749,1764 ****
if (ok)
{
! if (binoptab->code != UNKNOWN)
! equiv_value
! = gen_rtx_fmt_ee (binoptab->code, mode,
! copy_rtx (op0), copy_rtx (op1));
! else
! equiv_value = 0;
!
! emit_no_conflict_block (seq, target, op0, op1, equiv_value);
!
! return target;
}
}
--- 1746,1755 ----
if (ok)
{
! rtx equiv = gen_rtx_fmt_ee (binoptab->code, mode,
! copy_rtx (op0), copy_rtx (op1));
! emit_no_conflict_block (seq, result, op0, op1, equiv);
! return result;
}
}
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833