This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: rl78 vs cse vs memory_address_addr_space
- From: Segher Boessenkool <segher at kernel dot crashing dot org>
- To: DJ Delorie <dj at redhat dot com>
- Cc: Jeff Law <law at redhat dot com>, gcc at gcc dot gnu dot org
- Date: Tue, 7 Jul 2015 12:11:51 -0500
- Subject: Re: rl78 vs cse vs memory_address_addr_space
- Authentication-results: sourceware.org; auth=none
- References: <201507020414 dot t624EibE009579 at greed dot delorie dot com> <559AE466 dot 3080506 at redhat dot com> <201507062045 dot t66KjZOP018499 at greed dot delorie dot com> <20150706215836 dot GA20647 at gate dot crashing dot org>
On Mon, Jul 06, 2015 at 04:58:36PM -0500, Segher Boessenkool wrote:
> On Mon, Jul 06, 2015 at 04:45:35PM -0400, DJ Delorie wrote:
> > Combine gets as far as this:
> >
> > Trying 5 -> 9:
> > Failed to match this instruction:
> > (parallel [
> > (set (mem/v/j:QI (const_int 240 [0xf0]) [0 MEM[(volatile union un_per0 *)240B].BIT.no4+0 S1 A16])
> > (ior:QI (mem/v/j:QI (const_int 240 [0xf0]) [0 MEM[(volatile union un_per0 *)240B].BIT.no4+0 S1 A16])
> > (const_int 16 [0x10])))
> > (set (reg/f:HI 43)
> > (const_int 240 [0xf0]))
> > ])
> >
> > (the set is left behind because it's used for the second assignment)
> >
> > Both of those insns in the parallel are valid rl78 insns. I tried
> > adding that parallel as a define-and-split but combine doesn't split
> > it at the point where it inserts it, so it doesn't work right. If it
> > reduced those four instructions to the two in the parallel, but
> > without the parallel, it would probably work too.
>
> Did you try just a define_split instead? Ugly, but it should work I think.
So I built a rl78-elf cross and tried the example (s/union __BITS9/__BITS8/).
I couldn't get your exact code, I guess I need some special options?
But before combine it looks the same.
There is no combination of four instructions, the only combinations
combine makes here are 2->1 combinations, and they all succeed, except
that last one. Since combine won't do 2->2 no split will work. And,
as far as combine is concerned, a define_insn_and_split is a define_insn,
so that indeed won't help you either.
What you need is some form of uncse, like the attached hack (which doesn't
work in this case because the rtx costs prohibit it).
Segher
diff --git a/gcc/combine.c b/gcc/combine.c
index b97aa10..20d526f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -3928,8 +3938,10 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
&& XVECLEN (newpat, 0) == 2
&& GET_CODE (XVECEXP (newpat, 0, 0)) == SET
&& GET_CODE (XVECEXP (newpat, 0, 1)) == SET
- && (i1 || set_noop_p (XVECEXP (newpat, 0, 0))
- || set_noop_p (XVECEXP (newpat, 0, 1)))
+ && (1
+ || i1
+ || set_noop_p (XVECEXP (newpat, 0, 0))
+ || set_noop_p (XVECEXP (newpat, 0, 1)))
&& GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT
&& GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART
&& GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT