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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |collison at gcc dot gnu.org,
                   |                            |gretay at gcc dot gnu.org,
                   |                            |ktkachov at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
On the testcase, we have
(insn 56 55 50 2 (set (reg:SI 137 [ u+4 ])
        (const_int 2 [0x2])) "pr89434.c":9:5 652 {*arm_movsi_vfp}
     (nil))
...
(insn 53 52 24 2 (set (subreg:SI (reg:DI 118 [ _11 ]) 4)
        (minus:SI (minus:SI (reg:SI 139 [ _5+4 ])
                (reg:SI 137 [ u+4 ]))
            (ltu:SI (reg:CC_C 100 cc)
                (const_int 0 [0])))) "pr89434.c":10:12 29 {*subsi3_carryin}
     (nil))
in asmcons and IRA determines it can propagate the constant into the
instruction:
(insn 53 57 24 2 (set (subreg:SI (reg:DI 118 [ _11 ]) 4)
        (minus:SI (plus:SI (reg:SI 139 [ _5+4 ])
                (const_int -2 [0xfffffffffffffffe]))
            (ltu:SI (reg:CC_C 100 cc)
                (const_int 0 [0])))) "pr89434.c":10:12 30
{*subsi3_carryin_const}
     (expr_list:REG_DEAD (reg:SI 139 [ _5+4 ])
        (expr_list:REG_DEAD (reg:CC_C 100 cc)
            (nil))))
The RTL pattern looks good, but it actually emits
        sbc     r1, r3, #1
instruction, which is actually r1 = r3 + (-1) - carry aka r1 = r3 - 1 - carry
rather than r1 = r3 + (-2) - carry aka r1 = r3 - 2 - carry.
We shouldn't bitwise ~ the number, but negate it to get the constant we want.
And the *subsi3_carryin_compare_const looks totally wrong, not only it doesn't
contain even the PR70014 fix, but if it matches, it will match something
completely different from what it wants to match.  This define_insn change is
completely untested though.

Reply via email to