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.