This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ia64] [PR target/57491] internal compiler error: in ia64_split_tmode -O2, quadmath


Hello,
On 15 Nov 12:34, Eric Botcazou wrote:
> >   (insn 199 0 0 (set (reg:DI 14 r14)
> >               (mem:DI (post_inc:DI (reg/f:DI 15 r15 [447])) [3
> > *_61[_12]{lb: 1 sz: 64}.text+0 S8 A128])) -1 (nil))
> >   (insn 200 199 0 (set (reg:DI 15 r15)
> >                 (mem:DI (post_dec:DI (reg/f:DI 15 r15 [447])) [3
> > *_61[_12]{lb: 1 sz: 64}.text+8 S8 A64])) -1 (nil))
> >
> > Although r15 post_dec in second insn seems to be useless code seems to be
> > valid for me. What do you guys think?
>
> But the post_dec will clobber r15, won't it?
As far as I understand semantics of this insn:
  (insn 200 199 0 (set (reg:DI 15 r15)
      (mem:DI (post_dec:DI (reg/f:DI 15 r15 [447])) [3
      *_61[_12]{lb: 1 sz: 64}.text+8 S8 A64])) -1 (nil))
What is done is (in that sequence).
  1. Calculate address of MEM: get r15 value.
  2. Decrement r15 value.
  3. Load MEM in to r15.

Point 2 is useless as we kill it by 3.
So, it is clobbered and as mention in comment this is sometimes ok to
override pointer with pointer value.

My patch was bogus in that I thought that `dead' actually means that
if any part of address expression is changed - it becomes dead.

PR example. We're trying to split this:
(insn 77 180 79 4 (set (reg/v:TF 44 loc12 [orig:359 T8 ] [359])
        (mem:TF (post_modify:DI (reg/f:DI 14 r14 [435])
                (plus:DI (reg/f:DI 14 r14 [435])
                    (reg:DI 45 loc13 [orig:342 D.3347 ] [342]))) [2 *R1_102+0 S16 A128])) 1.i:2370 131 {*movtf_intern\
al}

and we have intersect of destination (actually it is going to
be a pair after split: <loc12, loc13>):
  (reg/v:TF 44 loc12 [orig:359 T8 ] [359])
and
  (mem:TF (post_modify:DI (reg/f:DI 14 r14 [435])
                     (plus:DI (reg/f:DI 14 r14 [435])
                              (reg:DI 45 loc13 [orig:342 D.3347 ] [342])))

If we take a look at these RTXes we see that they actually intersect by
loc13, but this is *not* killing address in r14.

Semantics which (will preserve r14 mem addr) is:
  1. Calculate addr of MEM: get r14 value.
  2. Set r14 += loc13.
  3. Load value at r14 into <loc12, loc13>.

If this sequence is correct then we have live address in loc13 after insn.
That is way setting `dead' in that case is incorrect.

We need to set `dead' flag only when address is actually going to be killed
by load.

Patch in the bottom. Test from PR pass.

Bootstrap (with Ada) is still in progress.

--
Thanks, K


---
 gcc/config/ia64/ia64.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index e6bd96d..d555ccc 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -1530,18 +1530,15 @@ ia64_split_tmode_move (rtx operands[])
       && reg_overlap_mentioned_p (operands[0], operands[1]))
     {
       rtx base = XEXP (operands[1], 0);
-      rtx first_write = gen_rtx_REG (DImode, REGNO (operands[0]));
       while (GET_CODE (base) != REG)
        base = XEXP (base, 0);

       if (REGNO (base) == REGNO (operands[0]))
-       {
-         reversed = true;
-         first_write = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
-       }
+       reversed = true;

-      if (GET_CODE (operands[0]) == REG
-         && reg_overlap_mentioned_p (first_write, operands[1]))
+      if (refers_to_regno_p (REGNO (operands[0]),
+                            REGNO (operands[0])+2,
+                            base, 0))
        dead = true;
     }
   /* Another reason to do the moves in reversed order is if the first


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]