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