[Bug rtl-optimization/68328] [4.9/5/6 Regression] wrong code at -O2 and -O3 on x86_64-linux-gnu

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Nov 16 10:47:00 GMT 2015


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

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

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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, we have there:
(insn 63 8 69 3 (set (reg:QI 0 ax [106])
        (mem/c:QI (symbol_ref:DI ("d") [flags 0x2]  <var_decl 0x7f17a01531c8
d>) [2 d+0 S1 A32])) pr68328.c:14 92 {*movqi_internal}
     (expr_list:REG_EQUIV (mem/c:QI (symbol_ref:DI ("d") [flags 0x2]  <var_decl
0x7f17a01531c8 d>) [2 d+0 S1 A32])
        (nil)))
(insn 69 63 15 3 (set (reg:SI 3 bx [orig:83 h ] [83])
        (if_then_else:SI (ne (reg:CCZ 17 flags)
                (const_int 0 [0]))
            (reg:SI 0 ax [106])
            (reg:SI 3 bx [orig:83 h ] [83]))) pr68328.c:14 952 {*movsicc_noc}
     (nil))
(insn 15 69 4 3 (set (reg:SI 1 dx [orig:99 D.1789 ] [99])
        (sign_extend:SI (reg/v:QI 3 bx [orig:83 h ] [83]))) pr68328.c:15 147
{extendqisi2}
     (nil))
...
(insn 65 18 66 4 (set (reg:SI 0 ax [orig:100 D.1790 ] [100])
        (plus:SI (reg:SI 3 bx [orig:83 h ] [83])
            (const_int -120 [0xffffffffffffff88]))) 258 {*leasi}
     (nil))
in *.split2, those are all spots where bx is mentioned.  As can be seen from
the source, h is only conditionally defined (but the condition is actually
true), and may also get its value from previous loop iteration (although that
is not the case here).  The ax from insn 65 (which is the only other spot where
bx is used) is then used only as QImode, so the bits outside of QImode don't
matter.
But REE in r206418 and later transforms this into:
(insn 63 8 70 3 (set (reg:SI 1 dx)
        (sign_extend:SI (mem/c:QI (symbol_ref:DI ("d") [flags 0x2]  <var_decl
0x7f17a01531c8 d>) [2 d+0 S1 A32]))) pr68328.c:14 147 {extendqisi2}
     (expr_list:REG_EQUIV (mem/c:QI (symbol_ref:DI ("d") [flags 0x2]  <var_decl
0x7f17a01531c8 d>) [2 d+0 S1 A32])
        (nil)))
(insn 70 63 69 3 (set (reg:SI 3 bx)
        (reg:SI 1 dx [orig:99 D.1789 ] [99])) pr68328.c:14 -1
     (nil))
(insn 69 70 4 3 (set (reg:SI 3 bx [orig:83 h ] [83])
        (if_then_else:SI (ne (reg:CCZ 17 flags)
                (const_int 0 [0]))
            (reg:SI 0 ax [106])
            (reg:SI 3 bx [orig:83 h ] [83]))) pr68328.c:14 952 {*movsicc_noc}
...
(insn 65 18 66 4 (set (reg:SI 0 ax [orig:100 D.1790 ] [100])
        (plus:SI (reg:SI 3 bx [orig:83 h ] [83])
            (const_int -120 [0xffffffffffffff88]))) 258 {*leasi}
     (nil))
which looks very wrong, originally the IF_THEN_ELSE had the memory load in ax
and bx has been previously either uninitialized, or from previous iteration.
But the changed code sets bx to the (now sign-extended) memory load, and leaves
ax uninitialized; but that is actually the value assigned to bx in the
movsicc_noc, so depending on what value %eax has upon entry to this function we
either fail or don't.


More information about the Gcc-bugs mailing list