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

--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
cse1 optimizes insn optimizes insn 15 away in:
(insn 10 9 11 2 (parallel [
            (set (reg:SI 84 [ _3 ])
                (plus:SI (reg:SI 96)
                    (reg:SI 92 [ _18 ])))
            (clobber (reg:CC 17 flags))
        ]) 185 {*addsi_1}
     (nil))
(insn 11 10 12 2 (set (reg:CCZ 17 flags)
        (compare:CCZ (reg:SI 84 [ _3 ])
            (const_int 1 [0x1]))) 11 {*cmpsi_1}
     (nil))
(insn 12 11 13 2 (set (reg:QI 98)
        (ne:QI (reg:CCZ 17 flags)
            (const_int 0 [0]))) 732 {*setcc_qi}
     (nil))
(insn 13 12 14 2 (set (reg:SI 97)
        (zero_extend:SI (reg:QI 98))) 119 {*zero_extendqisi2}
     (nil))
(insn 14 13 15 2 (set (reg:SI 89 [ _15 ])
        (reg:SI 97)) 67 {*movsi_internal}
     (nil))
(insn 15 14 16 2 (set (reg:CCZ 17 flags)
        (compare:CCZ (reg:SI 84 [ _3 ])
            (const_int 1 [0x1]))) 11 {*cmpsi_1}
     (nil))
(insn 16 15 17 2 (set (reg:QI 100)
        (eq:QI (reg:CCZ 17 flags)
            (const_int 0 [0]))) 732 {*setcc_qi}
     (nil))
which looks reasonable, nothing clobbers flags in between and insn 11 sets it
to the same value.

I think things go wrong during combine.
Before that revision we have
(insn 5 2 6 2 (set (reg:CCZ 17 flags)
        (compare:CCZ (mem/c:SI (symbol_ref:DI ("a") [flags 0x2]  <var_decl
0x7fc3d8edfb40 a>) [1 a+0 S4 A32])
            (const_int -2 [0xfffffffffffffffe]))) 11 {*cmpsi_1}
     (nil))
...
(insn 18 17 19 2 (set (reg:SI 97)
        (eq:SI (reg:CCZ 17 flags)
            (const_int 0 [0]))) 731 {*setcc_si_1_movzbl}
     (expr_list:REG_DEAD (reg:CC 17 flags)
        (nil)))
(insn 19 18 20 2 (set (reg:SI 102)
        (ne:SI (reg:CCZ 17 flags)
            (const_int 0 [0]))) 731 {*setcc_si_1_movzbl}
     (expr_list:REG_DEAD (reg:CC 17 flags)
        (nil)))
(insn 20 19 21 2 (parallel [
            (set (reg:SI 93 [ <retval> ])
                (minus:SI (reg:SI 102)
                    (reg:SI 97)))
            (clobber (reg:CC 17 flags))
        ]) 254 {*subsi_1}
     (expr_list:REG_DEAD (reg:SI 102)
        (expr_list:REG_DEAD (reg:SI 97)
            (expr_list:REG_UNUSED (reg:CC 17 flags)
                (nil)))))
(insn 21 20 25 2 (set (mem/c:SI (symbol_ref:DI ("b") [flags 0x2]  <var_decl
0x7fc3d8edfbd0 b>) [1 b+0 S4 A32])
        (reg:SI 93 [ <retval> ])) 67 {*movsi_internal}
     (nil))
which feels reasonable.  The testcase has UB when a == -2 (left shift by -1)
and otherwise sets b to 1.
But starting with r10-7268 combiner combines this into
(insn 5 2 6 2 (set (reg:CCZ 17 flags)
        (compare:CCZ (mem/c:SI (symbol_ref:DI ("a") [flags 0x2]  <var_decl
0x7f2bc69b4b40 a>) [1 a+0 S4 A32])
            (const_int -2 [0xfffffffffffffffe]))) 11 {*cmpsi_1}
     (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))
...
(insn 20 19 21 2 (set (reg:SI 93 [ <retval> ])
        (const_int 0 [0])) 67 {*movsi_internal}
     (nil))
(insn 21 20 25 2 (set (mem/c:SI (symbol_ref:DI ("b") [flags 0x2]  <var_decl
0x7f2bc69b4bd0 b>) [1 b+0 S4 A32])
        (reg:SI 93 [ <retval> ])) 67 {*movsi_internal}
     (nil))
which is wrong for the non-UB case of a not being -2.

Reply via email to