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

           Summary: Incorrect combiner transformation.
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: marcus.shawcr...@arm.com


Created attachment 22015
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=22015
Code fragment that exhibits miss compilation.

The change svn 163383 introduced a change causes incorrect compilation of
the attached code fragment at -O2. Found on ARM target, causing boehm garbage
collector to be miss compiled.

Prior to svn:163383 the compiler compiled the attached fragment as:

GC_is_marked:
    bic    r2, r0, #4080
    movw    r3, #:lower16:GC_arrays
    bic    r2, r2, #15
    movt    r3, #:upper16:GC_arrays
    mov    r1, r2, lsr #22
    ubfx    ip, r2, #12, #10
    rsb    r2, r2, r0
        ....

After svn:163383 we get:

GC_is_marked:
    bic    r3, r3, #4080
    movw    r2, #:lower16:GC_arrays
    bic    r3, r3, #15
    movt    r2, #:upper16:GC_arrays
    mov    r1, r3, lsr #22
    mov    r0, r0, asl #20
        ....

Note the first instruction refers to r3, rather than r0!

It looks to me that the issue arises in the combiner as follows, given:
(insn 2 4 3 2 (set (reg/v/f:SI 152 [ p ])
        (reg:SI 0 r0 [ p ])) mark.i:25 165 {*arm_movsi_insn}
     (expr_list:REG_DEAD (reg:SI 0 r0 [ p ])
        (nil)))

(note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)

(insn 6 3 7 2 (set (reg:SI 153)
        (and:SI (reg/v/f:SI 152 [ p ])
            (const_int -4081 [0xfffffffffffff00f]))) mark.i:26 69
{*arm_andsi3_insn}
     (nil))

(insn 7 6 8 2 (set (reg:SI 134 [ D.2028 ])
        (and:SI (reg:SI 153)
            (const_int -16 [0xfffffffffffffff0]))) mark.i:26 69
{*arm_andsi3_insn}
     (expr_list:REG_DEAD (reg:SI 153)
        (expr_list:REG_EQUAL (and:SI (reg/v/f:SI 152 [ p ])
                (const_int -4096 [0xfffffffffffff000]))
            (nil))))

(insn 8 7 9 2 (set (reg:SI 154)
        (minus:SI (reg/v/f:SI 152 [ p ])
            (reg:SI 134 [ D.2028 ]))) mark.i:28 29 {*arm_subsi3_insn}
     (expr_list:REG_DEAD (reg/v/f:SI 152 [ p ])
        (nil)))

The combiner does:

Trying 2, 6, 7 -> 8:
...

Successfully matched this instruction:
(set (reg:SI 134 [ D.2028 ])
    (and:SI (reg/v/f:SI 152 [ p ])
        (const_int -4096 [0xfffffffffffff000])))
Successfully matched this instruction:
(set (reg:SI 154)
    (and:SI (reg:SI 0 r0 [ p ])
        (const_int 4095 [0xfff])))
deferring deletion of insn with uid = 6.
deferring deletion of insn with uid = 2.

Subsequently insn uid == 2 is deleted leaving (reg 152) in the above fragment
undefined.

Reply via email to