On Sat, Jun 3, 2023 at 3:53 PM Takayuki 'January June' Suwa via
Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>
> This patch optimizes both the boolean evaluation of and the branching of
> EQ/NE against INT_MIN (-2147483648), by taking advantage of the specifi-
> cation the ABS machine instruction on Xtensa returns INT_MIN iff INT_MIN,
> otherwise non-negative value.

I wonder if this should be a generic expand improvement here.
You would definitely need to expand both ways and see if one is cost
more than the other.

Thanks,
Andrew Pinski


>
>     /* example */
>     int test0(int x) {
>       return (x == -2147483648);
>     }
>     int test1(int x) {
>       return (x != -2147483648);
>     }
>     extern void foo(void);
>     void test2(int x) {
>       if(x == -2147483648)
>         foo();
>     }
>     void test3(int x) {
>       if(x != -2147483648)
>         foo();
>     }
>
>     ;; before
>     test0:
>         movi.n  a9, -1
>         slli    a9, a9, 31
>         add.n   a2, a2, a9
>         nsau    a2, a2
>         srli    a2, a2, 5
>         ret.n
>     test1:
>         movi.n  a9, -1
>         slli    a9, a9, 31
>         add.n   a9, a2, a9
>         movi.n  a2, 1
>         moveqz  a2, a9, a9
>         ret.n
>     test2:
>         movi.n  a9, -1
>         slli    a9, a9, 31
>         bne     a2, a9, .L3
>         j.l     foo, a9
>     .L3:
>         ret.n
>     test3:
>         movi.n  a9, -1
>         slli    a9, a9, 31
>         beq     a2, a9, .L5
>         j.l     foo, a9
>     .L5:
>         ret.n
>
>     ;; after
>     test0:
>         abs     a2, a2
>         extui   a2, a2, 31, 1
>         ret.n
>     test1:
>         abs     a2, a2
>         srai    a2, a2, 31
>         addi.n  a2, a2, 1
>         ret.n
>     test2:
>         abs     a2, a2
>         bbci    a2, 31, .L3
>         j.l     foo, a9
>     .L3:
>         ret.n
>     test3:
>         abs     a2, a2
>         bbsi    a2, 31, .L5
>         j.l     foo, a9
>     .L5:
>         ret.n
>
> gcc/ChangeLog:
>
>         * config/xtensa/xtensa.md (*btrue_INT_MIN, *eqne_INT_MIN):
>         New insn_and_split patterns.
> ---
>  gcc/config/xtensa/xtensa.md | 64 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>
> diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
> index 87620934bbe..c9790babf75 100644
> --- a/gcc/config/xtensa/xtensa.md
> +++ b/gcc/config/xtensa/xtensa.md
> @@ -1940,6 +1940,37 @@
>                        (const_int 2)
>                        (const_int 3)))])
>
> +(define_insn_and_split "*btrue_INT_MIN"
> +  [(set (pc)
> +       (if_then_else (match_operator 2 "boolean_operator"
> +                       [(match_operand:SI 0 "register_operand" "r")
> +                        (const_int -2147483648)])
> +                     (label_ref (match_operand 1 ""))
> +                     (pc)))]
> +  "TARGET_ABS"
> +  "#"
> +  "&& can_create_pseudo_p ()"
> +  [(set (match_dup 3)
> +       (abs:SI (match_dup 0)))
> +   (set (pc)
> +       (if_then_else (match_op_dup 2
> +                       [(zero_extract:SI (match_dup 3)
> +                                         (const_int 1)
> +                                         (match_dup 4))
> +                        (const_int 0)])
> +                     (label_ref (match_dup 1))
> +                     (pc)))]
> +{
> +  operands[3] = gen_reg_rtx (SImode);
> +  operands[4] = GEN_INT (BITS_BIG_ENDIAN ? 0 : 31);
> +  operands[2] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[2])),
> +                               VOIDmode, XEXP (operands[2], 0),
> +                               const0_rtx);
> +}
> +  [(set_attr "type"    "jump")
> +   (set_attr "mode"    "none")
> +   (set_attr "length"  "6")])
> +
>  (define_insn "*ubtrue"
>    [(set (pc)
>         (if_then_else (match_operator 3 "ubranch_operator"
> @@ -3198,6 +3229,39 @@
>     (set_attr "mode"    "SI")
>     (set_attr "length"  "6")])
>
> +(define_insn_and_split "*eqne_INT_MIN"
> +  [(set (match_operand:SI 0 "register_operand" "=a")
> +       (match_operator 2 "boolean_operator"
> +               [(match_operand:SI 1 "register_operand" "r")
> +                (const_int -2147483648)]))]
> +  "TARGET_ABS"
> +  "#"
> +  "&& 1"
> +  [(set (match_dup 0)
> +       (abs:SI (match_dup 1)))
> +   (set (match_dup 0)
> +       (match_op_dup:SI 2
> +               [(match_dup 0)
> +                (const_int 31)]))
> +   (match_dup 3)]
> +{
> +  enum rtx_code code = GET_CODE (operands[2]);
> +  operands[2] = gen_rtx_fmt_ee ((code == EQ) ? LSHIFTRT : ASHIFTRT,
> +                               SImode, XEXP (operands[2], 0),
> +                               XEXP (operands[2], 1));
> +  operands[3] = (code != EQ) ? gen_addsi3 (operands[0],
> +                                          operands[0], const1_rtx)
> +                            : const0_rtx;
> +}
> +  [(set_attr "type"    "move")
> +   (set_attr "mode"    "SI")
> +   (set (attr "length")
> +       (if_then_else (match_test "GET_CODE (operands[2]) == EQ")
> +                     (const_int 3)
> +                     (if_then_else (match_test "TARGET_DENSITY")
> +                                   (const_int 5)
> +                                   (const_int 6))))])
> +
>  (define_peephole2
>    [(set (match_operand:SI 0 "register_operand")
>         (match_operand:SI 6 "reload_operand"))
> --
> 2.30.2

Reply via email to