diff options
author | Przemyslaw Wirkus <przemyslaw.wirkus@arm.com> | 2020-08-28 11:31:04 +0100 |
---|---|---|
committer | Przemyslaw Wirkus <przemyslaw.wirkus@arm.com> | 2020-08-28 11:34:03 +0100 |
commit | b648814c02eb418aaf27897c480452172ee96303 (patch) | |
tree | 2609928e5512d866d11da73221bf3aa52df853d6 /gcc | |
parent | 3b062fc43e1b564e2e18b5c89aa7b5463fcba735 (diff) | |
download | gcc-b648814c02eb418aaf27897c480452172ee96303.zip gcc-b648814c02eb418aaf27897c480452172ee96303.tar.gz gcc-b648814c02eb418aaf27897c480452172ee96303.tar.bz2 |
[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<mode>_any_const) is no longer the same as operand 1, and so
the pattern doesn't match the split condition.
Pattern cond_sub<mode>_any_const is being split by this patch into two
separate patterns:
* Pattern cond_sub<mode>_relaxed_const now matches const_int
SVE_RELAXED_GP operand.
* Pattern cond_sub<mode>_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<mode>_relaxed_const): Updated and renamed from
cond_sub<mode>_any_const pattern.
(cond_sub<mode>_strict_const): New pattern.
gcc/testsuite/ChangeLog:
PR target/96357
* gcc.target/aarch64/sve/pr96357.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/aarch64/aarch64-sve.md | 42 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sve/pr96357.c | 25 |
2 files changed, 62 insertions, 5 deletions
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 182813c..cd79aba 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<mode>_any_const" +;; +;; The subtraction predicate and the merge predicate are allowed to be +;; different. +(define_insn_and_rewrite "*cond_sub<mode>_relaxed_const" [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w") (unspec:SVE_FULL_F [(match_operand:<VPRED> 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.<Vetype>, %1/z, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2 movprfx\t%0.<Vetype>, %1/m, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%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<mode>_strict_const" + [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w") + (unspec:SVE_FULL_F + [(match_operand:<VPRED> 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.<Vetype>, %1/z, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2 + movprfx\t%0.<Vetype>, %1/m, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2 + #" + "&& reload_completed + && register_operand (operands[4], <MODE>mode) + && !rtx_equal_p (operands[0], operands[4])" + { + emit_insn (gen_vcond_mask_<mode><vpred> (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 0000000..e52867f --- /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} } } */ |