http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55547



             Bug #: 55547

           Summary: Alias analysis does not handle AND addresses correctly

    Classification: Unclassified

           Product: gcc

           Version: 4.8.0

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: rtl-optimization

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: ubiz...@gmail.com

            Target: alphaev68-unknown-linux-gnu





The patch that fixed alias analysis [1] triggered following testsuite failure

[2] on alphaev68-linux-gnu:



FAIL: gfortran.fortran-torture/execute/save_1.f90 execution,  -O2 

FAIL: gfortran.fortran-torture/execute/save_1.f90 execution,  -O2

-fomit-frame-pointer -finline-functions 

FAIL: gfortran.fortran-torture/execute/save_1.f90 execution,  -O2

-fomit-frame-pointer -finline-functions -funroll-loops 

FAIL: gfortran.fortran-torture/execute/save_1.f90 execution,  -O2

-fbounds-check 



The testcase fails in the line where i is checked for 26. The value is 0:



      subroutine foo (b)

        logical b

        integer i, j

        character*24 s

        save

        if (b) then

          i = 26

          j = 131

          s = 'This is a test string'

        else

          if (i .ne. 26 .or. j .ne. 131) call abort

          if (s .ne. 'This is a test string') call abort

        end if

      end subroutine foo



This is a runtime failure, but the problem can be seen with a crosscompiler,

configured with --target=alpha-linux-gnu.



The testcase should be compiled with "-O2 -mcpu=ev67 -mexplicit-relocs".



Before _208r.sched1, we have:



   10: r77:DI=high(`i.843')

   11: r78:SI=0x1a

   12: [r77:DI+low(`i.843')]=r78:SI

      REG_DEADr78:SI

      REG_DEADr77:DI

...

   42: r102:DI=r81:DI+low(`s.845')

      REG_EQUAL`s.845'

   43: r106:DI=[r102:DI+0xf&0xfffffffffffffff8]

   44: r105:DI=[r81:DI+low(`s.845')&0xfffffffffffffff8]

      REG_EQUAL[`s.845'&0xfffffffffffffff8]

 ...

   57: [r81:DI+low(`s.845')&0xfffffffffffffff8]=r105:DI

      REG_DEADr105:DI

      REG_DEADr81:DI



(The last sequence is part of alpha_expand_block_move, specifically an

unaligned access to the head of string "s.845"). In the above sequence, load

and store to i.843 and s.845 are lined one after another.



The problematic sequence is shown in function "foo" in _.208r.sched1 RTL dump,

after scheduler reordered instructions:



   17: r82:DI=high(`*$LC0')

   16: r81:DI=high(`s.845')

   70: r115:QI=0x20

   10: r77:DI=high(`i.843')

   18: r86:DI=r82:DI+low(`*$LC0')

      REG_EQUAL`*$LC0'

   42: r102:DI=r81:DI+low(`s.845')

      REG_EQUAL`s.845'

   19: r83:DI=[r82:DI+low(`*$LC0')&0xfffffffffffffff8]

      REG_DEADr82:DI

      REG_EQUAL[`*$LC0'&0xfffffffffffffff8]

   44: r105:DI=[r81:DI+low(`s.845')&0xfffffffffffffff8]

      REG_EQUAL[`s.845'&0xfffffffffffffff8]

   21: r89:DI=[r86:DI+0xf&0xfffffffffffffff8]

   20: r84:DI=[r86:DI+0x8&0xfffffffffffffff8]

   23: r91:DI=r86:DI&0x7

   11: r78:SI=0x1a

   43: r106:DI=[r102:DI+0xf&0xfffffffffffffff8]

...

   12: [r77:DI+low(`i.843')]=r78:SI

      REG_DEADr78:SI

      REG_DEADr77:DI

...

   57: [r81:DI+low(`s.845')&0xfffffffffffffff8]=r105:DI

      REG_DEADr105:DI

      REG_DEADr81:DI



As it happens, i lives inside "aligned" s address range:



(gdb) p &i

$3 = (PTR TO -> ( integer(kind=4) )) 0x120012090 <i.853>

(gdb) p &s

$4 = (PTR TO -> ( character*24 )) 0x120012094 <s.855>



Due to the way unaligned stores are implemented on alpha, where an aligned

address is read first, the value is inserted and the combination is stored back

to aligned address, we rewrite location of "i" with previous value, 0 in this

case.



To illustrate this problem, let's put breakpoints at the store of i (b1) and

store of s (b2):



   0x0000000120000a8c <+204>:   cmoveq  t10,0,t9

   0x0000000120000a90 <+208>:   ldah    t10,0(gp)

b1 0x0000000120000a94 <+212>:   stl     a3,-32640(t10)

   0x0000000120000a98 <+216>:   lda     a3,131

   0x0000000120000a9c <+220>:   or      t2,t8,t2

   0x0000000120000aa0 <+224>:   or      t3,t9,t3

   0x0000000120000aa4 <+228>:   ldah    t10,0(gp)

   0x0000000120000aa8 <+232>:   stb     t6,23(t0)

   0x0000000120000aac <+236>:   insqh   t2,t0,t8

   0x0000000120000ab0 <+240>:   mskqh   t5,t0,t5

   0x0000000120000ab4 <+244>:   stl     a3,-32644(t10)

   0x0000000120000ab8 <+248>:   insqh   t3,t0,t1

   0x0000000120000abc <+252>:   insql   t2,t0,t2

   0x0000000120000ac0 <+256>:   or      t5,t8,t5

   0x0000000120000ac4 <+260>:   stq_u   t5,15(t0)

   0x0000000120000ac8 <+264>:   insql   t3,t0,t3

   0x0000000120000acc <+268>:   or      t1,t2,t1

   0x0000000120000ad0 <+272>:   stq_u   t1,8(t0)

   0x0000000120000ad4 <+276>:   stb     a4,16(t0)

   0x0000000120000ad8 <+280>:   or      t4,t3,t4

b2 0x0000000120000adc <+284>:   stq_u   t4,-32636(t7)

   0x0000000120000ae0 <+288>:   stb     a5,17(t0)



Breakpoint 1, 0x0000000120000a94 in foo (b=.TRUE.) at save_1.f90:7

7                 i = 26

(gdb) p i

$5 = 0

(gdb) s

8                 j = 131

(gdb) p i

$6 = 26

(gdb) c

Continuing.



Breakpoint 2, 0x0000000120000adc in foo (b=.TRUE.) at save_1.f90:9

9                 s = 'This is a test string'

(gdb) p i

$7 = 26

(gdb) s

14            end subroutine foo

(gdb) p i

$8 = 0

(gdb) 



When compiled with additional -fno-schedule-insns, the test runs OK.



[1] http://gcc.gnu.org/ml/gcc-patches/2012-11/msg02225.html

[2] http://gcc.gnu.org/ml/gcc-testresults/2012-11/msg02492.html

Reply via email to