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.