https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69614

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bernds at gcc dot gnu.org

--- Comment #16 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #15)
> Will continue debugging tomorrow.

So, indeed, it looks like a RA bug to me, at least *.ira dump looks sane, and
*.reload is already wrong.  With the testcase from the previous comment, 
--- passes.def.xx       2016-02-16 21:43:38.000000000 +0100
+++ passes.def  2016-03-10 16:58:48.656378891 +0100
@@ -327,7 +327,7 @@ along with GCC; see the file COPYING3.
         we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c).
         However, this also causes us to misdiagnose cases that should be
         real warnings (e.g., testsuite/gcc.dg/pr18501.c).  */
-      NEXT_PASS (pass_dce);
+      /* NEXT_PASS (pass_dce); */
       /* Split critical edges before late uninit warning to reduce the
          number of false positives from it.  */
       NEXT_PASS (pass_split_crit_edges);
applied and the above mentioned command line options, I can see:
! earlier code copied the 128-bit argument l from [sp, #184] to [sp, #32]
...
        ldr     r2, [sp, #32]
        uxth    r1, r7
        eor     r3, r3, r2
        str     r3, [sp, #16]
        bl      __aeabi_uidiv
        ldr     r3, [sp, #36]
        lsr     r1, r7, #16
        ldr     r2, [sp, #40]
        str     r3, [sp, #20]
        ldr     r3, [sp, #160]
        eor     r3, r3, r2
        ldr     r2, [sp, #164]
        str     r3, [sp, #24]
        ldr     r3, [sp, #44]
        eor     r3, r3, r2
        str     r3, [sp, #28]
! the above 3 eor (xor) instructions are the only ones in the assembly, so
! easy to spot.  They are just 3, because already combiner? figured out that
! the second lowest word is xored with 0.  Anyway, the above stores the
! result of l ^= (F) { j[4], f }; into [sp, #16], and from debugging session
! on armv7hl, it is correctly (F) { 0x67784fdb22ULL, 0 } at that point in
! [sp, #16] and [sp, #32] is equal to [sp, #184] equal to
! (F) { 0x67784fdb22ULL, 1 }.
...
        mov     r9, r3
        mov     r3, #0
        uxth    r2, r2
        strd    r2, [sp, #16]
! this is the problematic instruction, RA needed to spill the result of
! zero_extendhidi2 instruction (REG_EXPR on there says j+4), and apparently
! decided to spill it into a slot where the l = l ^ ... value lives at that 
! point.  We have 0 now there.
        ldrd    r2, [sp]
...
        ldrd    r2, [sp, #16]
! this is the correspondig fill.
        adds    r2, r2, r6
        adc     r3, r3, r7
...
        ldr     r3, [sp, #20]
! this is the first instruction for the l[0] r>> 63 sequence, expects the
! current value of l[0] (i.e. result of the above xors) to live at [sp, #16].
        lsl     ip, r3, #1
        ldr     r3, [sp, #16]
        adc     r9, r7, #0
        mov     r7, #0
        orr     r3, ip, r3, lsr #31
! there are just two of these orr ..., lsr #31 instructions in foo, this is the
! first one of them, the second one follows shortly after that, both
participate
! in the rotation.  But, it rotates the DImode 0 instead of the expected
! 0x67784fdb22ULL.
        str     r3, [sp, #4]

I see this reuse of a still in use spill slot already in the *.reload dump, so
this is most likely some RA issue.
I also see in the *.reload/*.postreload dump:
(insn 146 602 701 2 (set (reg:SI 3 r3 [685])
        (xor:SI (reg:SI 3 r3 [632])
            (reg:SI 2 r2 [633]))) pr69614.c:14 103 {*arm_xorsi3}
     (nil))
(insn 701 146 659 2 (set (mem/c:SI (plus:SI (reg/f:SI 13 sp)
                (const_int 16 [0x10])) [4 %sfp+-104 S4 A64])
        (reg:SI 3 r3 [685])) pr69614.c:14 614 {*arm_movsi_vfp}
     (nil))
(insn 659 701 655 2 (clobber (mem/c:TI (plus:SI (reg/f:SI 102 sfp)
                (const_int -104 [0xffffffffffffff98])) [4 %sfp+-104 S16 A64]))
pr69614.c:14 -1
     (nil))
insn 146 is the pre-reload first xor, insn 701 is storing of the result into
the [sp, #16] memory slot, but the insn 659 inserted during LRA is just weird.
There is no corresponding clobber in *.ira at this point, there is just
(insn 150 104 146 2 (clobber (reg:TI 207 [ _119 ])) pr69614.c:14 -1
     (nil))
in *.ira a few instructions before that (which is ok, we clobber the 4xwordsize
pseudo before we assign it by 4 subreg stores), and that corresponds to
(insn 150 600 601 2 (clobber (mem/c:TI (plus:SI (reg/f:SI 102 sfp)
                (const_int -104 [0xffffffffffffff98])) [4 %sfp+-104 S16 A64]))
pr69614.c:14 -1
     (nil))
in *.reload/*.postreload a few instructions before the insn 146.

Reply via email to