On Tue, 2024-11-26 at 18:37 +0800, Jinyang He wrote:
> For {xv,v}{srl,sll,sra}, the constraint `vector_same_uimm6` cause overflow
> in when emit {w,h,b}. Since the number of bits shifted is the remainder of
> the register value, it is actually unnecessary to constrain the range.
> Simply mask the shift number with the unit-bit-width, without any
> constraint on the shift range.

Some comments below.

/* snip */

> diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
> index 457ed163f31..da3bc758a29 100644
> --- a/gcc/config/loongarch/lasx.md
> +++ b/gcc/config/loongarch/lasx.md
> @@ -1013,11 +1013,23 @@
>    [(set (match_operand:ILASX 0 "register_operand" "=f,f")
>       (lshiftrt:ILASX
>         (match_operand:ILASX 1 "register_operand" "f,f")
> -       (match_operand:ILASX 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
> +       (match_operand:ILASX 2 "reg_or_vector_same_uimm_operand" "f,Uuvx")))]
>    "ISA_HAS_LASX"
> -  "@
> -   xvsrl.<lasxfmt>\t%u0,%u1,%u2
> -   xvsrli.<lasxfmt>\t%u0,%u1,%E2"
> +{
> +  switch (which_alternative)
> +    {
> +    case 0:
> +      return "xvsrl.<lasxfmt>\t%u0,%u1,%u2";
> +    case 1:
> +      {
> +    unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (operands[2], 0));
> +    operands[2] = GEN_INT (val & (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1));
> +    return "xvsrli.<lasxfmt>\t%u0,%u1,%d2";

Incorrect indent.  Check editor and mail client setting?

> +      }
> +    default:
> +      gcc_unreachable ();
> +    }
> +}
>    [(set_attr "type" "simd_shift")
>     (set_attr "mode" "<MODE>")])
>  
> @@ -1026,11 +1038,23 @@
>    [(set (match_operand:ILASX 0 "register_operand" "=f,f")
>       (ashiftrt:ILASX
>         (match_operand:ILASX 1 "register_operand" "f,f")
> -       (match_operand:ILASX 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
> +       (match_operand:ILASX 2 "reg_or_vector_same_uimm_operand" "f,Uuvx")))]
>    "ISA_HAS_LASX"
> -  "@
> -   xvsra.<lasxfmt>\t%u0,%u1,%u2
> -   xvsrai.<lasxfmt>\t%u0,%u1,%E2"
> +{
> +  switch (which_alternative)
> +    {
> +    case 0:
> +      return "xvsra.<lasxfmt>\t%u0,%u1,%u2";
> +    case 1:
> +      {
> +    unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (operands[2], 0));
> +    operands[2] = GEN_INT (val & (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1));
> +    return "xvsrai.<lasxfmt>\t%u0,%u1,%d2";

Likewise.

> +      }
> +    default:
> +      gcc_unreachable ();
> +    }
> +}
>    [(set_attr "type" "simd_shift")
>     (set_attr "mode" "<MODE>")])
>  
> @@ -1039,11 +1063,23 @@
>    [(set (match_operand:ILASX 0 "register_operand" "=f,f")
>       (ashift:ILASX
>         (match_operand:ILASX 1 "register_operand" "f,f")
> -       (match_operand:ILASX 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
> +       (match_operand:ILASX 2 "reg_or_vector_same_uimm_operand" "f,Uuvx")))]
>    "ISA_HAS_LASX"
> -  "@
> -   xvsll.<lasxfmt>\t%u0,%u1,%u2
> -   xvslli.<lasxfmt>\t%u0,%u1,%E2"
> +{
> +  switch (which_alternative)
> +    {
> +    case 0:
> +      return "xvsll.<lasxfmt>\t%u0,%u1,%u2";
> +    case 1:
> +      {
> +    unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (operands[2], 0));
> +    operands[2] = GEN_INT (val & (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1));
> +    return "xvslli.<lasxfmt>\t%u0,%u1,%d2";

Likewise.

> +      }
> +    default:
> +      gcc_unreachable ();
> +    }
> +}
>    [(set_attr "type" "simd_shift")
>     (set_attr "mode" "<MODE>")])
>  
> diff --git a/gcc/config/loongarch/loongarch-protos.h 
> b/gcc/config/loongarch/loongarch-protos.h
> index bc1b94b41d3..be37f284f39 100644
> --- a/gcc/config/loongarch/loongarch-protos.h
> +++ b/gcc/config/loongarch/loongarch-protos.h
> @@ -113,8 +113,9 @@ extern rtx loongarch_return_addr (int, rtx);
>  
>  extern bool loongarch_const_vector_same_val_p (rtx, machine_mode);
>  extern bool loongarch_const_vector_same_bytes_p (rtx, machine_mode);
> -extern bool loongarch_const_vector_same_int_p (rtx, machine_mode, 
> HOST_WIDE_INT,
> -                                       HOST_WIDE_INT);
> +extern bool loongarch_const_vector_same_int_p (rtx, machine_mode,
> +                        HOST_WIDE_INT low = HOST_WIDE_INT_MIN,
> +                        HOST_WIDE_INT high = HOST_WIDE_INT_MAX);
>  extern bool loongarch_const_vector_shuffle_set_p (rtx, machine_mode);
>  extern bool loongarch_const_vector_bitimm_set_p (rtx, machine_mode);
>  extern bool loongarch_const_vector_bitimm_clr_p (rtx, machine_mode);
> diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
> index a9004290371..314544e012d 100644
> --- a/gcc/config/loongarch/lsx.md
> +++ b/gcc/config/loongarch/lsx.md
> @@ -879,11 +879,23 @@
>    [(set (match_operand:ILSX 0 "register_operand" "=f,f")
>       (lshiftrt:ILSX
>         (match_operand:ILSX 1 "register_operand" "f,f")
> -       (match_operand:ILSX 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
> +       (match_operand:ILSX 2 "reg_or_vector_same_uimm_operand" "f,Uuvx")))]
>    "ISA_HAS_LSX"
> -  "@
> -   vsrl.<lsxfmt>\t%w0,%w1,%w2
> -   vsrli.<lsxfmt>\t%w0,%w1,%E2"
> +{
> +  switch (which_alternative)
> +    {
> +    case 0:
> +      return "vsrl.<lsxfmt>\t%w0,%w1,%w2";
> +    case 1:
> +      {
> +    unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (operands[2], 0));
> +    operands[2] = GEN_INT (val & (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1));
> +    return "vsrli.<lsxfmt>\t%w0,%w1,%d2";

Likewise.

> +      }
> +    default:
> +      gcc_unreachable ();
> +    }
> +}
>    [(set_attr "type" "simd_shift")
>     (set_attr "mode" "<MODE>")])
>  
> @@ -891,11 +903,23 @@
>    [(set (match_operand:ILSX 0 "register_operand" "=f,f")
>       (ashiftrt:ILSX
>         (match_operand:ILSX 1 "register_operand" "f,f")
> -       (match_operand:ILSX 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
> +       (match_operand:ILSX 2 "reg_or_vector_same_uimm_operand" "f,Uuvx")))]
>    "ISA_HAS_LSX"
> -  "@
> -   vsra.<lsxfmt>\t%w0,%w1,%w2
> -   vsrai.<lsxfmt>\t%w0,%w1,%E2"
> +{
> +  switch (which_alternative)
> +    {
> +    case 0:
> +      return "vsra.<lsxfmt>\t%w0,%w1,%w2";
> +    case 1:
> +      {
> +    unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (operands[2], 0));
> +    operands[2] = GEN_INT (val & (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1));
> +    return "vsrai.<lsxfmt>\t%w0,%w1,%d2";

Likewise.

> +      }
> +    default:
> +      gcc_unreachable ();
> +    }
> +}
>    [(set_attr "type" "simd_shift")
>     (set_attr "mode" "<MODE>")])
>  
> @@ -903,11 +927,23 @@
>    [(set (match_operand:ILSX 0 "register_operand" "=f,f")
>       (ashift:ILSX
>         (match_operand:ILSX 1 "register_operand" "f,f")
> -       (match_operand:ILSX 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
> +       (match_operand:ILSX 2 "reg_or_vector_same_uimm_operand" "f,Uuvx")))]
>    "ISA_HAS_LSX"
> -  "@
> -   vsll.<lsxfmt>\t%w0,%w1,%w2
> -   vslli.<lsxfmt>\t%w0,%w1,%E2"
> +{
> +  switch (which_alternative)
> +    {
> +    case 0:
> +      return "vsll.<lsxfmt>\t%w0,%w1,%w2";
> +    case 1:
> +      {
> +    unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (operands[2], 0));
> +    operands[2] = GEN_INT (val & (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1));
> +    return "vslli.<lsxfmt>\t%w0,%w1,%d2";

Likewise.

> +      }
> +    default:
> +      gcc_unreachable ();
> +    }
> +}
>    [(set_attr "type" "simd_shift")
>     (set_attr "mode" "<MODE>")])
>  
> diff --git a/gcc/config/loongarch/predicates.md 
> b/gcc/config/loongarch/predicates.md
> index 95c2544cc2f..e744e4e61ea 100644
> --- a/gcc/config/loongarch/predicates.md
> +++ b/gcc/config/loongarch/predicates.md
> @@ -635,10 +635,10 @@
>    return loongarch_const_vector_same_int_p (op, mode, -31, 31);
>  })
>  
> -(define_predicate "const_vector_same_uimm6_operand"
> +(define_predicate "const_vector_same_uimm_operand"
>    (match_code "const_vector")
>  {
> -  return loongarch_const_vector_same_int_p (op, mode, 0, 63);
> +  return loongarch_const_vector_same_int_p (op, mode);
>  })
>  
>  (define_predicate "par_const_vector_shf_set_operand"
> @@ -663,6 +663,6 @@
>    (ior (match_operand 0 "register_operand")
>         (match_operand 0 "const_vector_same_ximm5_operand")))
>  
> -(define_predicate "reg_or_vector_same_uimm6_operand"
> +(define_predicate "reg_or_vector_same_uimm_operand"
>    (ior (match_operand 0 "register_operand")
> -       (match_operand 0 "const_vector_same_uimm6_operand")))
> +       (match_operand 0 "const_vector_same_uimm_operand")))
> diff --git 
> a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-shift-sameimm-vec.c 
> b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-shift-sameimm-vec.c
> new file mode 100644
> index 00000000000..73df6217c63
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-shift-sameimm-vec.c
> @@ -0,0 +1,72 @@
> +/* Test shift bits overflow in vector */
> +/* { dg-do compile } */
> +/* { dg-options "-mlasx -O2" } */
> +/* { dg-final { scan-assembler "xvslli.b.*,1" } } */

Am I correct that the issue has triggered an assembler error?  IIUC we
can change it to "dg-do assemble" and then we don't need to have all
those scan-assembler.

/* snip */

> diff --git 
> a/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-shift-sameimm-vec.c 
> b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-shift-sameimm-vec.c
> new file mode 100644
> index 00000000000..68e89e941e4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-shift-sameimm-vec.c
> @@ -0,0 +1,72 @@
> +/* Test shift bits overflow in vector */
> +/* { dg-do compile } */
> +/* { dg-options "-mlsx -O2" } */
> +/* { dg-final { scan-assembler "vslli.b.*,1" } } */

Likewise.


-- 
Xi Ruoyao <xry...@xry111.site>
School of Aerospace Science and Technology, Xidian University

Reply via email to