From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1816) id D107D385B53E; Wed, 7 Jun 2023 15:21:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D107D385B53E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686151289; bh=1z2GFvggW7PoiGRMRSnpedZEo76LnrCbzbyEFrM+Eg4=; h=From:To:Subject:Date:From; b=eNYULgHJMlLOCWv3siOijR2rllo0MxtuoFZCGtZ9t7kfbhBanrk+xCPq4d+Q76yE1 CFxXr7E+rwaSwVacn5L24t7lbmzVKDHQJzFAm7B4zK3LAEIiswmlGehxNxUvpBkaVD w6AMxF3PAFppB1CQYsg5rjebqqZOgdxDJaq4RVWs= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Kyrylo Tkachov To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-1609] aarch64: Represent SQXTUN with RTL operations X-Act-Checkin: gcc X-Git-Author: Kyrylo Tkachov X-Git-Refname: refs/heads/master X-Git-Oldrev: a053c659f6bbc2d2eaf61fb3aad8c52899d0deb7 X-Git-Newrev: b747f54a2a930da55330c2861cd1e344f67a88d9 Message-Id: <20230607152129.D107D385B53E@sourceware.org> Date: Wed, 7 Jun 2023 15:21:29 +0000 (GMT) List-Id: https://gcc.gnu.org/g:b747f54a2a930da55330c2861cd1e344f67a88d9 commit r14-1609-gb747f54a2a930da55330c2861cd1e344f67a88d9 Author: Kyrylo Tkachov Date: Wed Jun 7 16:20:57 2023 +0100 aarch64: Represent SQXTUN with RTL operations This patch removes UNSPEC_SQXTUN and uses organic RTL codes to represent the operation. SQXTUN is an odd one. It's described in the architecture as "Signed saturating extract Unsigned Narrow". It's not a straightforward ss_truncate nor a us_truncate. It is a sort of truncating signed clamp operation with limits derived from the unsigned extrema of the narrow mode: (truncate:N (smin:M (smax:M (reg:M) (const_int 0)) (const_int ))) This patch implements these semantics. I've checked that the vqmovun tests in advsimd-intrinsics.exp now get constant-folded and still pass validation, so I'm pretty confident in the semantics. Bootstrapped and tested on aarch64-none-linux-gnu and aarch64_be-none-elf. gcc/ChangeLog: * config/aarch64/aarch64-simd.md (aarch64_sqmovun): Rename to... (*aarch64_sqmovun_insn): ... This. Reimplement with RTL codes. (aarch64_sqmovun [SD_HSDI]): Reimplement with RTL codes. (aarch64_sqxtun2_le): Likewise. (aarch64_sqxtun2_be): Likewise. (aarch64_sqxtun2): Adjust for the above. (aarch64_sqmovun): New define_expand. * config/aarch64/iterators.md (UNSPEC_SQXTUN): Delete. (half_mask): New mode attribute. * config/aarch64/predicates.md (aarch64_simd_umax_half_mode): New predicate. Diff: --- gcc/config/aarch64/aarch64-simd.md | 59 +++++++++++++++++++++++++++++--------- gcc/config/aarch64/iterators.md | 3 +- gcc/config/aarch64/predicates.md | 8 ++++++ 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index b23067c6754..3cecc10f3e8 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -5438,28 +5438,55 @@ (define_insn "aarch64_sqmovun" [(set (match_operand: 0 "register_operand" "=w") - (unspec: [(match_operand:SD_HSDI 1 "register_operand" "w")] - UNSPEC_SQXTUN))] + (truncate: + (smin:SD_HSDI + (smax:SD_HSDI + (match_operand:SD_HSDI 1 "register_operand" "w") + (const_int 0)) + (const_int ))))] "TARGET_SIMD" "sqxtun\\t%0, %1" [(set_attr "type" "neon_sat_shift_imm_narrow_q")] ) -(define_insn "aarch64_sqmovun" +(define_insn "*aarch64_sqmovun_insn" [(set (match_operand: 0 "register_operand" "=w") - (unspec: [(match_operand:VQN 1 "register_operand" "w")] - UNSPEC_SQXTUN))] + (truncate: + (smin:VQN + (smax:VQN (match_operand:VQN 1 "register_operand" "w") + (match_operand:VQN 2 "aarch64_simd_or_scalar_imm_zero")) + (match_operand:VQN 3 "aarch64_simd_umax_half_mode"))))] "TARGET_SIMD" "sqxtun\\t%0, %1" [(set_attr "type" "neon_sat_shift_imm_narrow_q")] ) +(define_expand "aarch64_sqmovun" + [(set (match_operand: 0 "register_operand" "=w") + (truncate: + (smin:VQN + (smax:VQN (match_operand:VQN 1 "register_operand" "w") + (match_dup 2)) + (match_dup 3))))] + "TARGET_SIMD" + { + operands[2] = CONST0_RTX (mode); + operands[3] + = aarch64_simd_gen_const_vector_dup (mode, + GET_MODE_MASK (GET_MODE_INNER (mode))); + } +) + (define_insn "aarch64_sqxtun2_le" [(set (match_operand: 0 "register_operand" "=w") (vec_concat: (match_operand: 1 "register_operand" "0") - (unspec: - [(match_operand:VQN 2 "register_operand" "w")] UNSPEC_SQXTUN)))] + (truncate: + (smin:VQN + (smax:VQN + (match_operand:VQN 2 "register_operand" "w") + (match_operand:VQN 3 "aarch64_simd_or_scalar_imm_zero")) + (match_operand:VQN 4 "aarch64_simd_umax_half_mode")))))] "TARGET_SIMD && !BYTES_BIG_ENDIAN" "sqxtun2\\t%0., %2." [(set_attr "type" "neon_sat_shift_imm_narrow_q")] @@ -5468,8 +5495,12 @@ (define_insn "aarch64_sqxtun2_be" [(set (match_operand: 0 "register_operand" "=w") (vec_concat: - (unspec: - [(match_operand:VQN 2 "register_operand" "w")] UNSPEC_SQXTUN) + (truncate: + (smin:VQN + (smax:VQN + (match_operand:VQN 2 "register_operand" "w") + (match_operand:VQN 3 "aarch64_simd_or_scalar_imm_zero")) + (match_operand:VQN 4 "aarch64_simd_umax_half_mode"))) (match_operand: 1 "register_operand" "0")))] "TARGET_SIMD && BYTES_BIG_ENDIAN" "sqxtun2\\t%0., %2." @@ -5479,16 +5510,18 @@ (define_expand "aarch64_sqxtun2" [(match_operand: 0 "register_operand") (match_operand: 1 "register_operand") - (unspec: - [(match_operand:VQN 2 "register_operand")] UNSPEC_SQXTUN)] + (match_operand:VQN 2 "register_operand")] "TARGET_SIMD" { + rtx zeros = CONST0_RTX (mode); + rtx half_umax = aarch64_simd_gen_const_vector_dup (mode, + GET_MODE_MASK (GET_MODE_INNER (mode))); if (BYTES_BIG_ENDIAN) emit_insn (gen_aarch64_sqxtun2_be (operands[0], operands[1], - operands[2])); + operands[2], zeros, half_umax)); else emit_insn (gen_aarch64_sqxtun2_le (operands[0], operands[1], - operands[2])); + operands[2], zeros, half_umax)); DONE; } ) diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 9e1e17bc1b9..56ce1251e80 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -638,7 +638,6 @@ UNSPEC_FMULX ; Used in aarch64-simd.md. UNSPEC_USQADD ; Used in aarch64-simd.md. UNSPEC_SUQADD ; Used in aarch64-simd.md. - UNSPEC_SQXTUN ; Used in aarch64-simd.md. UNSPEC_SSRA ; Used in aarch64-simd.md. UNSPEC_USRA ; Used in aarch64-simd.md. UNSPEC_SRSHR ; Used in aarch64-simd.md. @@ -1025,6 +1024,8 @@ (define_mode_attr short_mask [(HI "65535") (QI "255")]) +(define_mode_attr half_mask [(HI "255") (SI "65535") (DI "4294967295")]) + ;; For constraints used in scalar immediate vector moves (define_mode_attr hq [(HI "h") (QI "q")]) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index d93fd86fa27..9391aba40c4 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -595,6 +595,14 @@ GET_MODE_UNIT_BITSIZE (GET_MODE (op)) / 2, GET_MODE_UNIT_BITSIZE (GET_MODE (op)) / 2)"))) +(define_predicate "aarch64_simd_umax_half_mode" + (and (match_code "const_vector") + (match_test "aarch64_const_vec_all_same_in_range_p (op, + (HOST_WIDE_INT_1U + << (GET_MODE_UNIT_BITSIZE (mode) / 2)) - 1, + (HOST_WIDE_INT_1U + << (GET_MODE_UNIT_BITSIZE (mode) / 2)) - 1)"))) + (define_predicate "aarch64_simd_shift_imm_vec_qi" (and (match_code "const_vector") (match_test "aarch64_const_vec_all_same_in_range_p (op, 1, 8)")))