[gcc r17-2820] RISC-V: Disallow unsupported vabd/vwabda patterns

Bohan Lei via Gcc-cvs <[email protected]> Thu, 30 Jul 2026 10:12:49 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:ceff533bb4f3c9a49fe30e53caef015961b56d5a

commit r17-2820-gceff533bb4f3c9a49fe30e53caef015961b56d5a
Author: Bohan Lei <[email protected]>
Date:   Thu Jul 23 11:03:37 2026 +0800

    RISC-V: Disallow unsupported vabd/vwabda patterns
    
    The Zvabd specification only defines vabd[u]/vwabda[u] for SEW 8 or 16.
    We should not allow unsupported SEW instructions to be generated.
    
    gcc/ChangeLog:
    
            * config/riscv/autovec-opt.md (*vwabda<su><mode>): Limit mode to
            VWEXTI_HS.
            (*vwabda_right<su><mode>): Ditto.
            * config/riscv/autovec.md (<su>abd<mode>3): Limit mode to VI_QH.
            * config/riscv/vector-iterators.md: New iterators.  VWEXTI
            rewritten using VWEXTI_HS and VWEXTI_D.
            * config/riscv/vector.md: Limit modes in Zvabd patterns except
            vabs.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/rvv/autovec/zvabd-1.c: Add test functions
            for cases where vabd/vwabda cannot be used.

Diff:
---
 gcc/config/riscv/autovec-opt.md                    | 16 ++++++------
 gcc/config/riscv/autovec.md                        |  8 +++---
 gcc/config/riscv/vector-iterators.md               | 29 +++++++---------------
 gcc/config/riscv/vector.md                         | 20 +++++++--------
 .../gcc.target/riscv/rvv/autovec/zvabd-1.c         | 23 +++++++++--------
 5 files changed, 44 insertions(+), 52 deletions(-)

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index cc84f6336c51..d210b05a8a2a 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -685,14 +685,14 @@
 [(set_attr "type" "viwalu")])
 
 (define_insn_and_split "*vwabda<su><mode>"
-  [(set (match_operand:VWEXTI 0 "register_operand" "+&vr")
-	(plus:VWEXTI
-	  (zero_extend:VWEXTI
+  [(set (match_operand:VWEXTI_HS 0 "register_operand" "+&vr")
+	(plus:VWEXTI_HS
+	  (zero_extend:VWEXTI_HS
 	    (unspec:<V_DOUBLE_TRUNC>
 	      [(match_operand:<V_DOUBLE_TRUNC> 1 "register_operand" "vr")
 	       (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand" "vr")]
 	      UNSPEC_VABD))
-	  (match_operand:VWEXTI 3 "register_operand" "0")))]
+	  (match_operand:VWEXTI_HS 3 "register_operand" "0")))]
   "TARGET_ZVABD && can_create_pseudo_p ()"
   "#"
   "&& 1"
@@ -707,10 +707,10 @@
 
 ;; have this since we don't canonicalize the plus in the presence of an unspec.
 (define_insn_and_split "*vwabda_right<su><mode>"
-  [(set (match_operand:VWEXTI 0 "register_operand" "+&vr")
-	(plus:VWEXTI
-	  (match_operand:VWEXTI 1 "register_operand" "0")
-	  (zero_extend:VWEXTI
+  [(set (match_operand:VWEXTI_HS 0 "register_operand" "+&vr")
+	(plus:VWEXTI_HS
+	  (match_operand:VWEXTI_HS 1 "register_operand" "0")
+	  (zero_extend:VWEXTI_HS
 	    (unspec:<V_DOUBLE_TRUNC>
 	      [(match_operand:<V_DOUBLE_TRUNC> 2 "register_operand" "vr")
 	       (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "vr")]
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f6ec19d0025f..964eed927c82 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -3080,10 +3080,10 @@
 ; == Absolute difference (not including sum)
 ; ========
 (define_insn_and_split "<su>abd<mode>3"
-  [(set (match_operand:V_VLSI 0 "register_operand" "=vr")
-       (unspec:V_VLSI
-	 [(match_operand:V_VLSI 1 "register_operand" "vr")
-	  (match_operand:V_VLSI 2 "register_operand" "vr")]
+  [(set (match_operand:VI_QH 0 "register_operand" "=vr")
+	(unspec:VI_QH
+	 [(match_operand:VI_QH 1 "register_operand" "vr")
+	  (match_operand:VI_QH 2 "register_operand" "vr")]
 	 UNSPEC_VABD))]
   "TARGET_ZVABD && can_create_pseudo_p ()"
   "#"
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 3de384093428..f236e71c67c7 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1258,30 +1258,11 @@
   (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_VECTOR_ELEN_64")
 ])
 
-(define_mode_iterator VWEXTI_D [
-  (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64")
-  (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64")
-
-  (V1DI "riscv_vector::vls_mode_valid_p (V1DImode) && TARGET_VECTOR_ELEN_64")
-  (V2DI "riscv_vector::vls_mode_valid_p (V2DImode) && TARGET_VECTOR_ELEN_64")
-  (V4DI "riscv_vector::vls_mode_valid_p (V4DImode) && TARGET_VECTOR_ELEN_64")
-  (V8DI "riscv_vector::vls_mode_valid_p (V8DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 64")
-  (V16DI "riscv_vector::vls_mode_valid_p (V16DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128")
-  (V32DI "riscv_vector::vls_mode_valid_p (V32DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 256")
-  (V64DI "riscv_vector::vls_mode_valid_p (V64DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 512")
-  (V128DI "riscv_vector::vls_mode_valid_p (V128DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 1024")
-  (V256DI "riscv_vector::vls_mode_valid_p (V256DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 2048")
-  (V512DI "riscv_vector::vls_mode_valid_p (V512DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 4096")
-])
-
-(define_mode_iterator VWEXTI [
+(define_mode_iterator VWEXTI_HS [
   RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_VECTOR_ELEN_64")
 
   RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_VECTOR_ELEN_64")
 
-  (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64")
-  (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64")
-
   (V1HI "riscv_vector::vls_mode_valid_p (V1HImode)")
   (V2HI "riscv_vector::vls_mode_valid_p (V2HImode)")
   (V4HI "riscv_vector::vls_mode_valid_p (V4HImode)")
@@ -1305,6 +1286,12 @@
   (V256SI "riscv_vector::vls_mode_valid_p (V256SImode) && TARGET_MIN_VLEN >= 1024")
   (V512SI "riscv_vector::vls_mode_valid_p (V512SImode) && TARGET_MIN_VLEN >= 2048")
   (V1024SI "riscv_vector::vls_mode_valid_p (V1024SImode) && TARGET_MIN_VLEN >= 4096")
+])
+
+(define_mode_iterator VWEXTI_D [
+  (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64")
+  (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64")
+
   (V1DI "riscv_vector::vls_mode_valid_p (V1DImode) && TARGET_VECTOR_ELEN_64")
   (V2DI "riscv_vector::vls_mode_valid_p (V2DImode) && TARGET_VECTOR_ELEN_64")
   (V4DI "riscv_vector::vls_mode_valid_p (V4DImode) && TARGET_VECTOR_ELEN_64")
@@ -1317,6 +1304,8 @@
   (V512DI "riscv_vector::vls_mode_valid_p (V512DImode) && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 4096")
 ])
 
+(define_mode_iterator VWEXTI [ VWEXTI_HS VWEXTI_D ])
+
 ;; Same iterator split reason as VF_ZVFHMIN and VF.
 (define_mode_iterator VWEXTF_ZVFHMIN [
   (RVVM8SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 72bdf421d0a1..ae8672999ebb 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -9264,8 +9264,8 @@
    (set (attr "avl_type_idx") (const_int 7))])
 
 (define_insn "@pred_vabd<su><mode>"
-  [(set (match_operand:V_VLSI 0 "register_operand"	    "=vd, vd, vr, vr")
-	(if_then_else:V_VLSI
+  [(set (match_operand:VI_QH 0 "register_operand"	    "=vd, vd, vr, vr")
+	(if_then_else:VI_QH
 	  (unspec:<VM>
 	    [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm, Wc1, Wc1")
 	     (match_operand 5 "vector_length_operand"	 " rK, rK, rK, rK")
@@ -9274,19 +9274,19 @@
 	     (match_operand 8 "const_int_operand"	 " i, i, i, i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-	  (unspec:V_VLSI
-	    [(match_operand:V_VLSI 3 "register_operand" "vr,vr,vr,vr")
-	     (match_operand:V_VLSI 4 "register_operand" "vr,vr,vr,vr")]
+	  (unspec:VI_QH
+	    [(match_operand:VI_QH 3 "register_operand" "vr,vr,vr,vr")
+	     (match_operand:VI_QH 4 "register_operand" "vr,vr,vr,vr")]
 	    UNSPEC_VABD)
-	  (match_operand:V_VLSI 2 "vector_merge_operand" "vu,0,vu,0")))]
+	  (match_operand:VI_QH 2 "vector_merge_operand" "vu,0,vu,0")))]
   "TARGET_ZVABD"
   "vabd<u>.vv\t%0,%3,%4%p1"
   [(set_attr "type" "vialu")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "@pred_widen_abd_plus<su><mode>"
-  [(set (match_operand:VWEXTI 0 "register_operand"      "+&vd,&vd,&vr,&vr")
-	(if_then_else:VWEXTI
+  [(set (match_operand:VWEXTI_HS 0 "register_operand"      "+&vd,&vd,&vr,&vr")
+	(if_then_else:VWEXTI_HS
 	  (unspec:<VM>
 	    [(match_operand:<VM> 1 "vector_mask_operand" "vm,vm,Wc1,Wc1")
 	     (match_operand 5 "vector_length_operand"    "rK,rK,rK,rK")
@@ -9295,12 +9295,12 @@
 	     (match_operand 8 "const_int_operand"      "i,i,i,i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-	  (unspec:VWEXTI
+	  (unspec:VWEXTI_HS
 	    [(match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "vr,vr,vr,vr")
 	     (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "vr,vr,vr,vr")
 	     (match_dup 0)]
 	    UNSPEC_VABDA)
-	  (match_operand:VWEXTI 2 "vector_merge_operand" "vu,0,vu,0")))]
+	  (match_operand:VWEXTI_HS 2 "vector_merge_operand" "vu,0,vu,0")))]
   "TARGET_ZVABD"
   "vwabda<u>.vv\t%0,%3,%4%p1"
   [(set_attr "type" "viwalu")
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvabd-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvabd-1.c
index 466522705b52..e8738f84160a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvabd-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvabd-1.c
@@ -3,8 +3,8 @@
 
 #include <stdint-gcc.h>
 
-static int
-abs (int i)
+static int64_t
+abs64 (int64_t i)
 {
   return i < 0 ? -i : i;
 }
@@ -16,7 +16,7 @@ abs (int i)
   {                                                                        \
     int i;                                                                 \
     for (i = 0; i < n; i++)                                                \
-      dst[i] = abs (a[i]);                                                 \
+      dst[i] = abs64 (a[i]);                                               \
   }
 
 #define TEST_VABD(TYPE1, TYPE2)                                            \
@@ -27,7 +27,7 @@ abs (int i)
   {                                                                        \
     int i;                                                                 \
     for (i = 0; i < n; i++)                                                \
-      dst[i] = abs (a[i] - b[i]);                                          \
+      dst[i] = abs64 ((int64_t) a[i] - (int64_t) b[i]);                    \
   }
 
 #define TEST_VWABDA(TYPE1, TYPE2)                                       \
@@ -37,7 +37,7 @@ abs (int i)
   {                                                                     \
     int i;                                                              \
     for (i = 0; i < n; i++)                                             \
-      dst[i] += abs (a[i] - b[i]);                                      \
+      dst[i] += abs64 ((int64_t) a[i] - (int64_t) b[i]);                \
   }
 
 #define TEST_ALL()                 \
@@ -47,14 +47,17 @@ abs (int i)
   TEST_VABD (uint8_t, uint8_t)     \
   TEST_VABD (int16_t, int16_t)     \
   TEST_VABD (uint16_t, uint16_t)   \
-  TEST_VWABDA (int16_t, int8_t)   \
-  TEST_VWABDA (uint16_t, uint8_t) \
-  TEST_VWABDA (int32_t, int16_t)  \
-  TEST_VWABDA (uint32_t, uint16_t)
+  TEST_VABD (int32_t, int32_t)     \
+  TEST_VWABDA (int16_t, int8_t)    \
+  TEST_VWABDA (uint16_t, uint8_t)  \
+  TEST_VWABDA (int32_t, int16_t)   \
+  TEST_VWABDA (uint32_t, uint16_t) \
+  TEST_VWABDA (int64_t, int32_t)   \
+  TEST_VWABDA (uint64_t, uint32_t)
 
 TEST_ALL()
 
-/* { dg-final { scan-assembler-times {\tvabs\.v} 2 } } */
+/* { dg-final { scan-assembler-times {\tvabs\.v} 5 } } */
 /* { dg-final { scan-assembler-times {\tvabd\.vv} 2 } } */
 /* { dg-final { scan-assembler-times {\tvabdu\.vv} 2 } } */
 /* { dg-final { scan-assembler-times {\tvwabda\.vv} 2 } } */