https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90311
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P2 Status|ASSIGNED |NEW CC| |ktkachov at gcc dot gnu.org, | |ramana at gcc dot gnu.org, | |rearnsha at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I'm afraid I need to punt on this, my limited understanding of the ARM cary-related handling is insufficient here. The code does x - ((x + a) <uns a) and in combiner matches (insn 11 10 12 2 (set (reg:CC_C 100 cc) (compare:CC_C (plus:SI (reg:SI 112 [ b.1_3 ]) (reg:SI 118 [ _15 ])) (reg:SI 112 [ b.1_3 ]))) "pr90311.c":13:10 17 {*compare_addsi2_op0} (expr_list:REG_DEAD (reg:SI 118 [ _15 ]) (nil))) (insn 13 12 15 2 (set (reg:SI 116 [ _9 ]) (minus:SI (reg:SI 112 [ b.1_3 ]) (ltu:SI (reg:CC_C 100 cc) (const_int 0 [0])))) "pr90311.c":13:5 31 {*subsi3_carryin_const0} (expr_list:REG_DEAD (reg:CC 100 cc) (expr_list:REG_DEAD (reg:SI 112 [ b.1_3 ]) (nil)))) which is equivalent in RTL, but clearly doesn't match what the HW is actually doing for the cmn and sbc instructions emitted for that. cmn r3, r1 when both r3 and r1 are 0 doesn't set carry, which is ok for the RTL in question, but sbc as I now read the documentation doesn't actually subtract carry, but subtracts negation of carry, so does something different from what the RTL says. I know I've added the *subsi3_carryin_const0 instruction myself, but it is just a special case of the preexisting *subsi3_carryin_const instruction that has been there before and if the new one doesn't match the RTL, the old one doesn't match it either. Therefore, I'm giving up on this, this needs somebody familiar with the architecture.