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.
[(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"
;; 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")]
; == 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 ()"
"#"
(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)")
(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")
(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")
(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")
(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")
(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")
#include <stdint-gcc.h>
-static int
-abs (int i)
+static int64_t
+abs64 (int64_t i)
{
return i < 0 ? -i : i;
}
{ \
int i; \
for (i = 0; i < n; i++) \
- dst[i] = abs (a[i]); \
+ dst[i] = abs64 (a[i]); \
}
#define TEST_VABD(TYPE1, TYPE2) \
{ \
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) \
{ \
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() \
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 } } */