diff mbox

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

Message ID 20131115135559.GA57982@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Kirill Yukhin Nov. 15, 2013, 1:55 p.m. UTC
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(-)

Comments

Kirill Yukhin Nov. 15, 2013, 2:11 p.m. UTC | #1
On 15 Nov 16:55, Kirill Yukhin wrote:
> Bootstrap (with Ada) is still in progress.

Passed for me (seems here is no Jeff's patch)
Kirill Yukhin Nov. 15, 2013, 4:47 p.m. UTC | #2
Hello,
On 15 Nov 17:11, Kirill Yukhin wrote:
> On 15 Nov 16:55, Kirill Yukhin wrote:
> > Bootstrap (with Ada) is still in progress.
> 
> Passed for me (seems here is no Jeff's patch)
On recent trunk with patch applied, I've got:
/export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c: In function 'tree_node* elaborate_expression_1(tree, \
Entity_Id, tree, bool, bool)':
/export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: fallthru edge after unconditional jump \
in bb 10
 }
 ^
/export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: wrong number of branch edges after unco\
nditional jump in bb 10
/export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: verify_flow_info: Incorrect fallthru 10\
->12
/export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: wrong insn in the fallthru edge
(barrier 683 682 112)
/export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: internal compiler error: in rtl_verify_fallthr\
u, at cfgrtl.c:2854
0x40000000015fee1f _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
        /export/users/kyukhin/gcc/git/gcc/gcc/rtl-error.c:109
Please submit a full bug report,

Seems like not connected to split TF/TI mode...

--
Thanks, K
Jeff Law Nov. 15, 2013, 4:52 p.m. UTC | #3
On 11/15/13 09:47, Kirill Yukhin wrote:
> Hello,
> On 15 Nov 17:11, Kirill Yukhin wrote:
>> On 15 Nov 16:55, Kirill Yukhin wrote:
>>> Bootstrap (with Ada) is still in progress.
>>
>> Passed for me (seems here is no Jeff's patch)
> On recent trunk with patch applied, I've got:
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c: In function 'tree_node* elaborate_expression_1(tree, \
> Entity_Id, tree, bool, bool)':
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: fallthru edge after unconditional jump \
> in bb 10
>   }
>   ^
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: wrong number of branch edges after unco\
> nditional jump in bb 10
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: verify_flow_info: Incorrect fallthru 10\
> ->12
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: wrong insn in the fallthru edge
> (barrier 683 682 112)
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: internal compiler error: in rtl_verify_fallthr\
> u, at cfgrtl.c:2854
> 0x40000000015fee1f _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
>          /export/users/kyukhin/gcc/git/gcc/gcc/rtl-error.c:109
> Please submit a full bug report,
>
> Seems like not connected to split TF/TI mode...
Right, that's the bug in ifcvt.c.  I posted a patch late last night...

jeff
Jeff Law Nov. 15, 2013, 6:20 p.m. UTC | #4
On 11/15/13 09:47, Kirill Yukhin wrote:
> Hello,
> On 15 Nov 17:11, Kirill Yukhin wrote:
>> On 15 Nov 16:55, Kirill Yukhin wrote:
>>> Bootstrap (with Ada) is still in progress.
>>
>> Passed for me (seems here is no Jeff's patch)
> On recent trunk with patch applied, I've got:
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c: In function 'tree_node* elaborate_expression_1(tree, \
> Entity_Id, tree, bool, bool)':
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: fallthru edge after unconditional jump \
> in bb 10
>   }
>   ^
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: wrong number of branch edges after unco\
> nditional jump in bb 10
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: verify_flow_info: Incorrect fallthru 10\
> ->12
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: error: wrong insn in the fallthru edge
> (barrier 683 682 112)
> /export/users/kyukhin/gcc/git/gcc/gcc/ada/gcc-interface/decl.c:6303:1: internal compiler error: in rtl_verify_fallthr\
> u, at cfgrtl.c:2854
> 0x40000000015fee1f _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
>          /export/users/kyukhin/gcc/git/gcc/gcc/rtl-error.c:109
> Please submit a full bug report,
>
> Seems like not connected to split TF/TI mode...
Fixed on the trunk now.

jeff
Eric Botcazou Nov. 16, 2013, 9:03 a.m. UTC | #5
> 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.

That depends on the semantics of the hardware instruction though, does it 
really guarantee 1/2/3 in that order?

> 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.

The patch looks good to me if you also adjust the last sentence in the comment 
just above the block:

  /* It is possible for reload to decide to overwrite a pointer with
     the value it points to.  In that case we have to do the loads in
     the appropriate order so that the pointer is not destroyed too
     early.  Also we must not generate a postmodify for that second
     load, or rws_access_regno will die.  */

Something like "And we must not generate a postmodify for the second load if
the destination register overlaps with the base register".

Thanks for fixing this.
Kirill Yukhin Nov. 18, 2013, 7:32 a.m. UTC | #6
On 16 Nov 10:03, Eric Botcazou wrote:
> > 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.
> 
> That depends on the semantics of the hardware instruction though, does it 
> really guarantee 1/2/3 in that order?
I've read into IA-64 Spec and it states that if we have
same destination and address registers with post-update form then
`Illegal instruction' should be raised.
This not affects my recent patch.

> The patch looks good to me if you also adjust the last sentence in the comment 
> just above the block:
> 
>   /* It is possible for reload to decide to overwrite a pointer with
>      the value it points to.  In that case we have to do the loads in
>      the appropriate order so that the pointer is not destroyed too
>      early.  Also we must not generate a postmodify for that second
>      load, or rws_access_regno will die.  */
> 
> Something like "And we must not generate a postmodify for the second load if
> the destination register overlaps with the base register".
Thanks, I'll check it in with proposed comment fix today.
Bootstrap (with all languages) pass.

--
Thanks, K
diff mbox

Patch

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