On Wed, Nov 11, 2026 at 10:19 AM Jiawei <[email protected]> wrote:
>
> Exclude left rotations from the masked register-count patterns that
> emit ROR without negating the count.
>
> gcc/ChangeLog:
>
>         * config/aarch64/aarch64.md
>         (*aarch64_<optab>_reg_<mode>3_mask1): Exclude left rotations.
>         (*aarch64_<optab>_reg_di3_mask2): Likewise.
>         * config/aarch64/aarch64.cc
>         (selftest::aarch64_test_masked_rotate): New function.
>         (selftest::aarch64_run_selftests): Call it.

Ok.


>
> ---
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index 
> ef39942f8fb202b1cf8371d45cb4d35847f9c288..50a8c7b83d4fc4c6e6e8c3aa00d259b9217081e1
>  100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -6163,7 +6163,8 @@
>           (match_operator 4 "subreg_lowpart_operator"
>            [(and:GPI (match_operand:GPI 2 "register_operand" "r")
>                      (match_operand 3 "const_int_operand" "n"))])))]
> -  "(~INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1)) == 0"
> +  "!<is_rotl>
> +   && (~INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1)) == 0"
>    "<shift>\t%<w>0, %<w>1, %<w>2"
>    [(set_attr "type" "shift_reg")]
>  )
> @@ -6227,7 +6228,8 @@
>           (match_operator 4 "subreg_lowpart_operator"
>            [(and:SI (match_operand:SI 2 "register_operand" "r")
>                     (match_operand 3 "const_int_operand" "n"))])))]
> -  "((~INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode) - 1)) == 0)"
> +  "!<is_rotl>
> +   && ((~INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode) - 1)) == 0)"
>  {
>    rtx xop[3];
>    xop[0] = operands[0];
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 
> 730a1fee835982df6627c870bc6849776e82642d..b4dae29cf4b427a6435417155ff4c2cb79ad3714
>  100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -34417,6 +34417,35 @@
>
>  extern void aarch64_json_tunings_tests ();
>
> +/* Masked register counts must not turn a left rotate into a right rotate.  
> */
> +
> +static void
> +aarch64_test_masked_rotate ()
> +{
> +  for (auto mode : { SImode, DImode })
> +    for (auto count_mode : { SImode, DImode })
> +      {
> +       if (mode == SImode && count_mode == DImode)
> +         continue;
> +       rtx dest = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER + 1);
> +       rtx value = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER + 2);
> +       rtx count = gen_rtx_REG (count_mode, LAST_VIRTUAL_REGISTER + 3);
> +       count = gen_rtx_AND (count_mode, count,
> +                            GEN_INT (GET_MODE_BITSIZE (mode) - 1));
> +       count = gen_rtx_SUBREG (QImode, count,
> +                               subreg_lowpart_offset (QImode, count_mode));
> +       for (auto code : { ASHIFT, ASHIFTRT, LSHIFTRT, ROTATERT, ROTATE })
> +         {
> +           rtx op = gen_rtx_fmt_ee (code, mode, value, count);
> +           int icode = recog (gen_rtx_SET (dest, op), nullptr, nullptr);
> +           if (code == ROTATE)
> +             ASSERT_EQ (icode, -1);
> +           else
> +             ASSERT_TRUE (icode >= 0);
> +         }
> +      }
> +}
> +
>  /* Run all target-specific selftests.  */
>
>  static void
> @@ -34427,6 +34456,7 @@
>    aarch64_test_sysreg_encoding_clashes ();
>    aarch64_test_sve_folding ();
>    aarch64_json_tunings_tests ();
> +  aarch64_test_masked_rotate ();
>  }
>
>  } // namespace selftest
>

Reply via email to