diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index b5c551ad650e1a83416d5fbbbdd38e3fa3beb532..1f356d04d5b3542ac9ce51bc315c81d1fff91f21 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -3303,38 +3303,74 @@ DONE; }) -(define_insn "aarch64_w" +(define_insn "aarch64_subw" [(set (match_operand: 0 "register_operand" "=w") - (ADDSUB: (match_operand: 1 "register_operand" "w") - (ANY_EXTEND: - (match_operand:VD_BHSI 2 "register_operand" "w"))))] + (minus: (match_operand: 1 "register_operand" "w") + (ANY_EXTEND: + (match_operand:VD_BHSI 2 "register_operand" "w"))))] "TARGET_SIMD" - "w\\t%0., %1., %2." - [(set_attr "type" "neon__widen")] + "subw\\t%0., %1., %2." + [(set_attr "type" "neon_sub_widen")] ) -(define_insn "aarch64_w_internal" +(define_insn "aarch64_subw_internal" [(set (match_operand: 0 "register_operand" "=w") - (ADDSUB: (match_operand: 1 "register_operand" "w") - (ANY_EXTEND: - (vec_select: - (match_operand:VQW 2 "register_operand" "w") - (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))))] + (minus: (match_operand: 1 "register_operand" "w") + (ANY_EXTEND: + (vec_select: + (match_operand:VQW 2 "register_operand" "w") + (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))))] "TARGET_SIMD" - "w\\t%0., %1., %2." - [(set_attr "type" "neon__widen")] + "subw\\t%0., %1., %2." + [(set_attr "type" "neon_sub_widen")] ) -(define_insn "aarch64_w2_internal" +(define_insn "aarch64_subw2_internal" [(set (match_operand: 0 "register_operand" "=w") - (ADDSUB: (match_operand: 1 "register_operand" "w") - (ANY_EXTEND: - (vec_select: - (match_operand:VQW 2 "register_operand" "w") - (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))))] + (minus: (match_operand: 1 "register_operand" "w") + (ANY_EXTEND: + (vec_select: + (match_operand:VQW 2 "register_operand" "w") + (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))))] "TARGET_SIMD" - "w2\\t%0., %1., %2." - [(set_attr "type" "neon__widen")] + "subw2\\t%0., %1., %2." + [(set_attr "type" "neon_sub_widen")] +) + +(define_insn "aarch64_addw" + [(set (match_operand: 0 "register_operand" "=w") + (plus: + (ANY_EXTEND: (match_operand:VD_BHSI 2 "register_operand" "w")) + (match_operand: 1 "register_operand" "w")))] + "TARGET_SIMD" + "addw\\t%0., %1., %2." + [(set_attr "type" "neon_add_widen")] +) + +(define_insn "aarch64_addw_internal" + [(set (match_operand: 0 "register_operand" "=w") + (plus: + (ANY_EXTEND: + (vec_select: + (match_operand:VQW 2 "register_operand" "w") + (match_operand:VQW 3 "vect_par_cnst_lo_half" ""))) + (match_operand: 1 "register_operand" "w")))] + "TARGET_SIMD" + "addw\\t%0., %1., %2." + [(set_attr "type" "neon_add_widen")] +) + +(define_insn "aarch64_addw2_internal" + [(set (match_operand: 0 "register_operand" "=w") + (plus: + (ANY_EXTEND: + (vec_select: + (match_operand:VQW 2 "register_operand" "w") + (match_operand:VQW 3 "vect_par_cnst_hi_half" ""))) + (match_operand: 1 "register_operand" "w")))] + "TARGET_SIMD" + "addw2\\t%0., %1., %2." + [(set_attr "type" "neon_add_widen")] ) (define_expand "aarch64_saddw2" diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vect_su_add_sub.c b/gcc/testsuite/gcc.target/aarch64/simd/vect_su_add_sub.c new file mode 100644 index 0000000000000000000000000000000000000000..338da54f6281c90e1c6b1c59fa50d9b719005c77 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/vect_su_add_sub.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +/* Ensure we use the signed/unsigned extend vectorized add and sub + instructions. */ +#define N 1024 + +int a[N]; +long c[N]; +long d[N]; +unsigned int ua[N]; +unsigned long uc[N]; +unsigned long ud[N]; + +void +add () +{ + for (int i = 0; i < N; i++) + d[i] = a[i] + c[i]; +} +/* { dg-final { scan-assembler-times "\[ \t\]saddw2\[ \t\]+" 1 } } */ +/* { dg-final { scan-assembler-times "\[ \t\]saddw\[ \t\]+" 1 } } */ + +void +subtract () +{ + for (int i = 0; i < N; i++) + d[i] = c[i] - a[i]; +} +/* { dg-final { scan-assembler-times "\[ \t\]ssubw2\[ \t\]+" 1 } } */ +/* { dg-final { scan-assembler-times "\[ \t\]ssubw\[ \t\]+" 1 } } */ + +void +uadd () +{ + for (int i = 0; i < N; i++) + ud[i] = ua[i] + uc[i]; +} +/* { dg-final { scan-assembler-times "\[ \t\]uaddw2\[ \t\]+" 1 } } */ +/* { dg-final { scan-assembler-times "\[ \t\]uaddw\[ \t\]+" 1 } } */ + +void +usubtract () +{ + for (int i = 0; i < N; i++) + ud[i] = uc[i] - ua[i]; +} +/* { dg-final { scan-assembler-times "\[ \t\]usubw2\[ \t\]+" 1 } } */ +/* { dg-final { scan-assembler-times "\[ \t\]usubw\[ \t\]+" 1 } } */