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

            Bug ID: 64557
           Summary: get_addr in true_dependence_1 cannot handle VALUE
                    inside an expr
           Product: gcc
           Version: 4.9.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wmi at google dot com

We saw a bug in dse2 after porting the patch
https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01209.html from gcc-4_9 to
google-4_9 branch. From the analysis below, I think the problem exists but is
hidden in trunk and gcc-4_9 too. I cannot extract a small testcase to show it
independently without turning on some optimization in google-4_9, so I just
described it here:

We have such IR in a case:

The IR before dse2:
(insn/f 67 4 68 2 (set (mem:DI (pre_dec:DI (reg/f:DI 7 sp)) [0  S8 A8])
        (reg/f:DI 6 bp)) contentads/adx/mixer/auction/candidate.cc:14 -1
     (nil))
(insn/f 68 67 69 2 (set (reg/f:DI 6 bp)
        (reg/f:DI 7 sp)) contentads/adx/mixer/auction/candidate.cc:14 -1
     (nil))
(insn/f 70 69 71 2 (parallel [
            (set (reg/f:DI 7 sp)
                (plus:DI (reg/f:DI 7 sp)
                    (const_int -24 [0xffffffffffffffe8])))
            (clobber (reg:CC 17 flags))
            (clobber (mem:BLK (scratch) [0  A8]))
        ]) contentads/adx/mixer/auction/candidate.cc:14 -1
     (nil))
(note 71 70 2 2 NOTE_INSN_PROLOGUE_END)
....
(insn 7 3 9 2 (set (mem/c:SI (reg/f:DI 7 sp) [0 MEM[(void *)&D.3507754]+0 S4
A128])
        (const_int 0 [0])) ./ads/base/money.h:67 90 {*movsi_internal}
     (nil))
(insn 9 7 10 2 (set (mem/c:HI (reg/f:DI 7 sp) [0 MEM[(void *)&D.3507754]+0 S2
A128])
        (const_int 21333 [0x5355])) ./ads/base/money.h:68 92 {*movhi_internal}
     (nil))
(insn 10 9 11 2 (set (mem/c:QI (plus:DI (reg/f:DI 7 sp)
                (const_int 2 [0x2])) [0 MEM[(void *)&D.3507754]+2 S1 A16])
        (const_int 68 [0x44])) ./ads/base/money.h:68 93 {*movqi_internal}
     (nil))
(insn 11 10 12 2 (set (reg:SI 0 ax [orig:87 D.3507754 ] [87])
        (mem/c:SI (reg/f:DI 7 sp) [0 D.3507754+0 S4 A128]))
./ads/base/money.h:302 90 {*movsi_internal}
     (expr_list:REG_EQUIV (mem/c:SI (plus:DI (reg/f:DI 20 frame)
                (const_int -16 [0xfffffffffffffff0])) [0 D.3507754+0 S4 A128])
        (nil)))
...
(insn 15 13 17 2 (set (mem/c:SI (reg/f:DI 7 sp) [0 MEM[(void *)&D.3507756]+0 S4
A128])
        (const_int 0 [0])) ./ads/base/money.h:67 90 {*movsi_internal}
     (nil))

The IR after dse2:
The store in insn 10 is deleted. The other part is the same as above.

(mem/c:QI (plus:DI (reg/f:DI 7 sp) (const_int 2 [0x2])) in insn10 is regarded
to have no alias with (mem/c:SI (reg/f:DI 7 sp) in insn11, which is wrong. This
is because with the applied patch, get_addr is used to extract original
addresses for x_addr and mem_addr before they are used to find_base_term and
used in base_alias_check. See the description of x_addr and mem_addr below:

x is (mem/c:SI (reg/f:DI 7 sp)
x_addr before calling get_addr is:
(value:DI 4:12939 @0x84355f8/0x84354a0)
x_addr after calling get_addr is:
(plus:DI (value:DI 3:8637 @0x84355e8/0x8435478)
    (const_int -24 [0xffffffffffffffe8]))
x_addr_base is: (address:DI -4)

mem is (mem/c:QI (plus:DI (reg/f:DI 7 sp) (const_int 2 [0x2]))
mem_addr before calling get_addr is:
(plus:DI (value:DI 4:12939 @0x84355f8/0x84354a0)
    (const_int 2 [0x2]))
mem_addr after calling get_addr is:  // Notice: get_addr cannot handle plus
expr, so it returns the origin expr.
(plus:DI (value:DI 4:12939 @0x84355f8/0x84354a0)
    (const_int 2 [0x2]))
mem_addr_base is: (address:DI -1)

// value:DI 4:12939 @0x84355f8/0x84354a0 corresponds to reg/f:DI 7 sp
// value:DI 3:8637 @0x84355e8/0x8435478 corresponds to reg/f:DI 6 bp
// address:DI -1 corresponds to reg/f:DI 7 sp
// address:DI -4 corresponds to reg/f:DI 6 bp

x_addr_base and mem_addr_base are different, and unique_base_value_p will
return true for (address:DI -1) and (address:DI -4), so base_alias_check will
return 0, which is wrong.

I think the root cause of the problem is get_addr can only handle VALUE but
cannot handle VALUE inside an expr, like:(plus:DI (value:DI 4:12939
@0x84355f8/0x84354a0) (const_int 2 [0x2])), so find_base_term cannot know
x_addr and mem_addr actually have the same base.

Reply via email to