This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] combine leaves superfluous mem subregs
- From: Andreas Krebbel <krebbel1 at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 17 Jun 2005 13:41:37 +0200
- Subject: [PATCH] combine leaves superfluous mem subregs
Hi,
working on a patch for the s390 back end I've noticed that combine generates
pointless subregs which can't be handled by reload.
e.g. combine replaces the pseudo in:
(subreg:SF (reg:SI 42)) with a memory location to:
(subreg:SF (mem:SI (reg:SI 43))) and reload complaines in push_reload about that
subreg.
I think combine should have simplified this to:
(mem:SF (reg:SI 43))
The attached patch adds a call to simplify_subreg after make_compound_operation
has called itself with the operand of this subreg. Additionally it removes an
optimization in make_compound_statement which is already done by simplify_subreg.
Unfortunately I can't come up with a testcase showing the failure with current gcc.
In most cases these contructs do not lead to an abort in reload because eliminate_regs
reduces (subreg (mem)) to (mem) whenever possible but only if the memory location uses
an eliminable reg (reload1.c:2551).
Bootstrapped on s390, s390x and i686 without testsuite regressions.
OK for mainline?
Bye,
-Andreas-
2005-06-17 Andreas Krebbel <krebbel1@de.ibm.com>
* combine.c (make_compound_operation): Use simplify_subreg. Deleted
a optimization already done by simplify_subreg.
Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.491
diff -p -c -r1.491 combine.c
*** gcc/combine.c 7 Jun 2005 14:30:15 -0000 1.491
--- gcc/combine.c 17 Jun 2005 08:16:05 -0000
*************** make_compound_operation (rtx x, enum rtx
*** 6731,6771 ****
what it originally did, do this SUBREG as a force_to_mode. */
tem = make_compound_operation (SUBREG_REG (x), in_code);
! if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x))
! && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem))
! && subreg_lowpart_p (x))
! {
! rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0,
! NULL_RTX, 0);
!
! /* If we have something other than a SUBREG, we might have
! done an expansion, so rerun ourselves. */
! if (GET_CODE (newer) != SUBREG)
! newer = make_compound_operation (newer, in_code);
!
! return newer;
! }
!
! /* If this is a paradoxical subreg, and the new code is a sign or
! zero extension, omit the subreg and widen the extension. If it
! is a regular subreg, we can still get rid of the subreg by not
! widening so much, or in fact removing the extension entirely. */
! if ((GET_CODE (tem) == SIGN_EXTEND
! || GET_CODE (tem) == ZERO_EXTEND)
! && subreg_lowpart_p (x))
! {
! if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (tem))
! || (GET_MODE_SIZE (mode) >
! GET_MODE_SIZE (GET_MODE (XEXP (tem, 0)))))
! {
! if (! SCALAR_INT_MODE_P (mode))
! break;
! tem = gen_rtx_fmt_e (GET_CODE (tem), mode, XEXP (tem, 0));
! }
! else
! tem = gen_lowpart (mode, XEXP (tem, 0));
return tem;
! }
break;
default:
--- 6731,6763 ----
what it originally did, do this SUBREG as a force_to_mode. */
tem = make_compound_operation (SUBREG_REG (x), in_code);
!
! {
! rtx simplified;
! simplified = simplify_subreg (GET_MODE (x), tem, GET_MODE (tem),
! SUBREG_BYTE (x));
!
! if (simplified)
! tem = simplified;
!
! if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x))
! && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem))
! && subreg_lowpart_p (x))
! {
! rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0,
! NULL_RTX, 0);
!
! /* If we have something other than a SUBREG, we might have
! done an expansion, so rerun ourselves. */
! if (GET_CODE (newer) != SUBREG)
! newer = make_compound_operation (newer, in_code);
!
! return newer;
! }
!
! if (simplified)
return tem;
! }
break;
default: