From b648814c02eb418aaf27897c480452172ee96303 Mon Sep 17 00:00:00 2001 From: Przemyslaw Wirkus Date: Fri, 28 Aug 2020 11:31:04 +0100 Subject: [PATCH] [PATCH PR96357][GCC][AArch64]: could not split insn UNSPEC_COND_FSUB with AArch64 SVE Problem is related to that operand 4 (In original pattern cond_sub_any_const) is no longer the same as operand 1, and so the pattern doesn't match the split condition. Pattern cond_sub_any_const is being split by this patch into two separate patterns: * Pattern cond_sub_relaxed_const now matches const_int SVE_RELAXED_GP operand. * Pattern cond_sub_strict_const now matches const_int SVE_STRICT_GP operand. * Remove aarch64_sve_pred_dominates_p condition from both patterns. gcc/ChangeLog: PR target/96357 * config/aarch64/aarch64-sve.md (cond_sub_relaxed_const): Updated and renamed from cond_sub_any_const pattern. (cond_sub_strict_const): New pattern. gcc/testsuite/ChangeLog: PR target/96357 * gcc.target/aarch64/sve/pr96357.c: New test. --- gcc/config/aarch64/aarch64-sve.md | 42 ++++++++++++++++--- .../gcc.target/aarch64/sve/pr96357.c | 25 +++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/pr96357.c diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 182813c1c5c..cd79aba90ec 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -5234,21 +5234,22 @@ ;; Predicated floating-point subtraction from a constant, merging with an ;; independent value. -(define_insn_and_rewrite "*cond_sub_any_const" +;; +;; The subtraction predicate and the merge predicate are allowed to be +;; different. +(define_insn_and_rewrite "*cond_sub_relaxed_const" [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w") (unspec:SVE_FULL_F [(match_operand: 1 "register_operand" "Upl, Upl, Upl") (unspec:SVE_FULL_F [(match_operand 5) - (match_operand:SI 6 "aarch64_sve_gp_strictness") + (const_int SVE_RELAXED_GP) (match_operand:SVE_FULL_F 2 "aarch64_sve_float_arith_immediate") (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w")] UNSPEC_COND_FSUB) (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")] UNSPEC_SEL))] - "TARGET_SVE - && !rtx_equal_p (operands[3], operands[4]) - && aarch64_sve_pred_dominates_p (&operands[5], operands[1])" + "TARGET_SVE && !rtx_equal_p (operands[3], operands[4])" "@ movprfx\t%0., %1/z, %3.\;fsubr\t%0., %1/m, %0., #%2 movprfx\t%0., %1/m, %3.\;fsubr\t%0., %1/m, %0., #%2 @@ -5271,6 +5272,37 @@ [(set_attr "movprfx" "yes")] ) +;; Predicated floating-point subtraction from a constant, merging with an +;; independent value. +;; +;; The subtraction predicate and the merge predicate must be the same. +(define_insn_and_rewrite "*cond_sub_strict_const" + [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w") + (unspec:SVE_FULL_F + [(match_operand: 1 "register_operand" "Upl, Upl, Upl") + (unspec:SVE_FULL_F + [(match_dup 1) + (const_int SVE_STRICT_GP) + (match_operand:SVE_FULL_F 2 "aarch64_sve_float_arith_immediate") + (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w")] + UNSPEC_COND_FSUB) + (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")] + UNSPEC_SEL))] + "TARGET_SVE && !rtx_equal_p (operands[3], operands[4])" + "@ + movprfx\t%0., %1/z, %3.\;fsubr\t%0., %1/m, %0., #%2 + movprfx\t%0., %1/m, %3.\;fsubr\t%0., %1/m, %0., #%2 + #" + "&& reload_completed + && register_operand (operands[4], mode) + && !rtx_equal_p (operands[0], operands[4])" + { + emit_insn (gen_vcond_mask_ (operands[0], operands[3], + operands[4], operands[1])); + operands[4] = operands[3] = operands[0]; + } + [(set_attr "movprfx" "yes")] +) ;; Register merging forms are handled through SVE_COND_FP_BINARY. ;; ------------------------------------------------------------------------- diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c b/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c new file mode 100644 index 00000000000..e52867f5729 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=armv8.2-a+sve" } */ + +int d; + +void +f1(char f, char *g, char *h, char *l, char *n) { + double i = d, j = 1.0 - f, k = j ? d : j; + if (k == 1.0) + i = 0.0; + *l = *n = *g = *h = i * 0.5; +} + +void +f2() { + int a, m, c; + for (c = 2048; c; c--) { + char b = a++; + f1(b, m, m + 1, m + 2, m + 3); /*{ dg-warning {passing argument [0-9]+ of 'f1' makes pointer from integer without a cast} } */ + m += 4; + } +} + +/* { dg-final { scan-assembler {\tmovprfx\tz[0-9]+, z[0-9]+} } } */ +/* { dg-final { scan-assembler {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1.0} } } */ -- 2.30.2