i386: Improve ix86_expand_int_movcc
authorJakub Jelinek <jakub@redhat.com>
Thu, 28 Apr 2022 15:41:49 +0000 (17:41 +0200)
committerJakub Jelinek <jakub@redhat.com>
Thu, 28 Apr 2022 15:41:49 +0000 (17:41 +0200)
commitcb1758d95cc12e3f2d6c0e295288e4867c2e7197
tree2b5b868fb16c3ab12a67dbf2b712c020dea15008
parent12cc2b32991c05aba200a11bda3c382564185c8b
i386: Improve ix86_expand_int_movcc

When working on PR105338, I've noticed that in some cases we emit
unnecessarily long sequence which has then higher seq_cost than necessary.

E.g. when ix86_expand_int_movcc is called with
operands[0] (reg/v:SI 83 [ i ])
operands[1] (eq (reg/v:SI 83 [ i ]) (const_int 0 [0]))
operands[2] (reg/v:SI 83 [ i ])
operands[3] (const_int -2 [0xfffffffffffffffe])
i.e. r83 = r83 == 0 ? r83 : -2 which with my PR105338 patch is equivalent to
r83 = r83 == 0 ? 0 : -2, we emit:
(insn 24 0 25 (set (reg:CC 17 flags)
        (compare:CC (reg/v:SI 83 [ i ])
            (const_int 1 [0x1]))) 11 {*cmpsi_1}
     (nil))
(insn 25 24 26 (parallel [
            (set (reg:SI 85)
                (if_then_else:SI (ltu:SI (reg:CC 17 flags)
                        (const_int 0 [0]))
                    (const_int -1 [0xffffffffffffffff])
                    (const_int 0 [0])))
            (clobber (reg:CC 17 flags))
        ]) 1192 {*x86_movsicc_0_m1}
     (nil))
(insn 26 25 27 (set (reg:SI 85)
        (not:SI (reg:SI 85))) 683 {*one_cmplsi2_1}
     (nil))
(insn 27 26 28 (parallel [
            (set (reg:SI 85)
                (and:SI (reg:SI 85)
                    (const_int -2 [0xfffffffffffffffe])))
            (clobber (reg:CC 17 flags))
        ]) 533 {*andsi_1}
     (nil))
(insn 28 27 0 (set (reg/v:SI 83 [ i ])
        (reg:SI 85)) 81 {*movsi_internal}
     (nil))
which has seq_cost (seq, true) 24.  But it could have just cost 20
if we didn't decide to use a fresh temporary r85 and used r83 instead
- we could avoid the copy at the end.
The reason for it is in the 2 reg_overlap_mentioned_p calls,
the destination (out) indeed overlaps op0 - it is the same register,
but I don't see why that is a problem, this is in a code path where
we've already called
ix86_expand_carry_flag_compare (code, op0, op1, &compare_op)
earlier, so the fact that we've out overlaps op0 or op1 shouldn't matter
because insn 24 above is already emitted, we should just care if
it overlaps whatever we got from that ix86_expand_carry_flag_compare
call, i.e. compare_op, otherwise we can overwrite out just fine;
we also know at that point that the last 2 operands of ?: are constants.

2022-04-28  Jakub Jelinek  <jakub@redhat.com>

* config/i386/i386-expand.cc (ix86_expand_int_movcc): Create a
temporary only if out overlaps compare_op, not when it overlaps
op0 or op1.
gcc/config/i386/i386-expand.cc