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