> On 10 Sep 2026, at 19:52, Dominic P <[email protected]> wrote:
> 
> Kyrill's review of v2 pointed out that the sqxtun patterns are written
> with more complex RTL than the instruction needs, and that us_truncate
> of an smax against zero should be what they match.  This rewrites them
> that way, so the shape the vectoriser produces for MAX_EXPR <0, x> fed
> into IFN_SAT_TRUNC is now matched by the sqxtun pattern itself and v2's
> extra define_insn is gone.
> 
> The rewrite covers more than the two patterns named in the review.
> sqxtun2, sqshrun, sqshrun2, sqrshrun and sqrshrun2 wrap their results in
> the same truncate/smin/smax clamp against half_mask, so converting only
> the sqxtun pair would have left two spellings of "saturate into the
> unsigned narrow mode" in one file; they are converted too.  The named
> expanders build the us_truncate form directly, which is what keeps the
> vqmovun_*, vqshrun_n_* and vqrshrun_n_* intrinsics working: they reach
> the patterns through gen_* rather than through recog on a combination.
> 
> aarch64_simd_umax_half_mode and aarch64_simd_umax_quarter_mode lose their
> last users and are removed.  The scalar sqshrun/sqrshrun define_insns are
> unchanged: they compute in the wide mode and the expander takes a
> lowpart, so there is no truncate for the clamp to fold into.
> 
> The vqmovun/vqshrun_n/vqrshrun_n tests in
> gcc.target/aarch64/advsimd-intrinsics compare against expected values and
> run under qemu, so the family already has execution coverage; the new
> test only checks that the vectoriser's form reaches sqxtun.
> 
> Bootstrapped and regression tested on x86_64-pc-linux-gnu, and
> cross-tested on aarch64-linux-gnu under qemu (aarch64.exp, simd.exp,
> advsimd-intrinsics.exp, vect.exp).
> 
> Assisted-by: Claude Opus 5 (Anthropic)
> 

Ok.
Thanks for doing this.
Kyrill

> gcc/ChangeLog:
> 
> * config/aarch64/predicates.md (aarch64_simd_umax_half_mode)
> (aarch64_simd_umax_quarter_mode): Remove.
> * config/aarch64/aarch64-simd.md (aarch64_sqmovun<mode>)
> (*aarch64_sqmovun<mode>_insn<vczle><vczbe>)
> (aarch64_sqxtun2<mode>_le, aarch64_sqxtun2<mode>_be)
> (aarch64_sqxtun2<mode>)
> (*aarch64_sqshrun_n<mode>_insn<vczle><vczbe>)
> (aarch64_sqshrun_n<mode>)
> (*aarch64_sqrshrun_n<mode>_insn<vczle><vczbe>)
> (aarch64_sqrshrun_n<mode>, aarch64_sqshrun2_n<mode>_insn_le)
> (aarch64_sqshrun2_n<mode>_insn_be, aarch64_sqshrun2_n<mode>)
> (aarch64_sqrshrun2_n<mode>_insn_le)
> (aarch64_sqrshrun2_n<mode>_insn_be, aarch64_sqrshrun2_n<mode>):
> Match an us_truncate of an smax instead of a truncate of an smin
> of an smax.
> 
> gcc/testsuite/ChangeLog:
> 
> * gcc.target/aarch64/vect-sat-trunc-3.c: New test.
> 
> Signed-off-by: Dominic P <[email protected]>
> ---
> Resend of v3: the previous copy had its "---" separator line mangled into the 
> first line of this note, so git am would have folded the note into the commit 
> message.  Patch content identical.
> 
> v3: as Kyrill suggested, us_truncate of an smax against zero is now the RTL
> these patterns match, and v2's added pattern is gone.  I applied the same
> conversion to the rest of the family that used the truncate/smin/smax
> spelling (sqxtun2, sqshrun, sqshrun2, sqrshrun, sqrshrun2) so the file has
> only one spelling for it.
> 
> On the simplify-rtx canonicalisation you suggested: once the expanders emit
> us_truncate (smax (x, 0)) directly, nothing in the tree produces
> truncate (smin (smax (x, 0), umax)) any more, and I could not find a path
> that reaches it from C either - a scalar truncate becomes a lowpart subreg
> first under TRULY_NOOP_TRUNCATION, and the vector shape needs five insns
> where combine allows four.  It would be dead code as things stand, so I
> left it out rather than add a rule nothing exercises.  I am happy to add it
> as insurance for producers of the old form if you would still like it.
> 
> gcc/config/aarch64/aarch64-simd.md            | 211 +++++++-----------
> gcc/config/aarch64/predicates.md              |  15 --
> .../gcc.target/aarch64/vect-sat-trunc-3.c     |  41 ++++
> 3 files changed, 125 insertions(+), 142 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/aarch64/vect-sat-trunc-3.c
> 
> diff --git a/gcc/config/aarch64/aarch64-simd.md 
> b/gcc/config/aarch64/aarch64-simd.md
> index 12dcabb7a15..27ad3920fd7 100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -6242,12 +6242,10 @@
> 
> (define_insn "aarch64_sqmovun<mode>"
>   [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
> - (truncate:<VNARROWQ>
> -  (smin:SD_HSDI
> -    (smax:SD_HSDI
> -      (match_operand:SD_HSDI 1 "register_operand" "w")
> -      (const_int 0))
> -    (const_int <half_mask>))))]
> + (us_truncate:<VNARROWQ>
> +  (smax:SD_HSDI
> +    (match_operand:SD_HSDI 1 "register_operand" "w")
> +    (const_int 0))))]
>    "TARGET_SIMD"
>    "sqxtun\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
>    [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
> @@ -6255,11 +6253,9 @@
> 
> (define_insn "*aarch64_sqmovun<mode>_insn<vczle><vczbe>"
>   [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
> - (truncate:<VNARROWQ>
> -  (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"))))]
> + (us_truncate:<VNARROWQ>
> +  (smax:VQN (match_operand:VQN 1 "register_operand" "w")
> +    (match_operand:VQN 2 "aarch64_simd_or_scalar_imm_zero"))))]
>   "TARGET_SIMD"
>   "sqxtun\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
>   [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
> @@ -6267,17 +6263,12 @@
> 
> (define_expand "aarch64_sqmovun<mode>"
>   [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
> - (truncate:<VNARROWQ>
> -  (smin:VQN
> -    (smax:VQN (match_operand:VQN 1 "register_operand" "w")
> -      (match_dup 2))
> -    (match_dup 3))))]
> + (us_truncate:<VNARROWQ>
> +  (smax:VQN (match_operand:VQN 1 "register_operand" "w")
> +    (match_dup 2))))]
>   "TARGET_SIMD"
>   {
>     operands[2] = CONST0_RTX (<MODE>mode);
> -    operands[3]
> -      = aarch64_simd_gen_const_vector_dup (<MODE>mode,
> - GET_MODE_MASK (GET_MODE_INNER (<VNARROWQ>mode)));
>   }
> )
> 
> @@ -6285,12 +6276,10 @@
>   [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
> (vec_concat:<VNARROWQ2>
>  (match_operand:<VNARROWQ> 1 "register_operand" "0")
> -  (truncate:<VNARROWQ>
> -    (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")))))]
> +  (us_truncate:<VNARROWQ>
> +    (smax:VQN
> +      (match_operand:VQN 2 "register_operand" "w")
> +      (match_operand:VQN 3 "aarch64_simd_or_scalar_imm_zero")))))]
>   "TARGET_SIMD && !BYTES_BIG_ENDIAN"
>   "sqxtun2\\t%0.<V2ntype>, %2.<Vtype>"
>    [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
> @@ -6299,12 +6288,10 @@
> (define_insn "aarch64_sqxtun2<mode>_be"
>   [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
> (vec_concat:<VNARROWQ2>
> -  (truncate:<VNARROWQ>
> -    (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")))
> +  (us_truncate:<VNARROWQ>
> +    (smax:VQN
> +      (match_operand:VQN 2 "register_operand" "w")
> +      (match_operand:VQN 3 "aarch64_simd_or_scalar_imm_zero")))
>  (match_operand:<VNARROWQ> 1 "register_operand" "0")))]
>   "TARGET_SIMD && BYTES_BIG_ENDIAN"
>   "sqxtun2\\t%0.<V2ntype>, %2.<Vtype>"
> @@ -6318,14 +6305,12 @@
>   "TARGET_SIMD"
>   {
>     rtx zeros = CONST0_RTX (<MODE>mode);
> -    rtx half_umax = aarch64_simd_gen_const_vector_dup (<MODE>mode,
> - GET_MODE_MASK (GET_MODE_INNER (<VNARROWQ>mode)));
>     if (BYTES_BIG_ENDIAN)
>       emit_insn (gen_aarch64_sqxtun2<mode>_be (operands[0], operands[1],
> -       operands[2], zeros, half_umax));
> +       operands[2], zeros));
>     else
>       emit_insn (gen_aarch64_sqxtun2<mode>_le (operands[0], operands[1],
> -       operands[2], zeros, half_umax));
> +       operands[2], zeros));
>     DONE;
>   }
> )
> @@ -7586,14 +7571,12 @@
> 
> (define_insn "*aarch64_sqshrun_n<mode>_insn<vczle><vczbe>"
>   [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
> - (truncate:<VNARROWQ>
> -  (smin:VQN
> -    (smax:VQN
> -      (ashiftrt:VQN
> - (match_operand:VQN 1 "register_operand" "w")
> - (match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> -      (match_operand:VQN 3 "aarch64_simd_imm_zero"))
> -    (match_operand:VQN 4 "aarch64_simd_umax_half_mode"))))]
> + (us_truncate:<VNARROWQ>
> +  (smax:VQN
> +    (ashiftrt:VQN
> +      (match_operand:VQN 1 "register_operand" "w")
> +      (match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> +    (match_operand:VQN 3 "aarch64_simd_imm_zero"))))]
>   "TARGET_SIMD"
>   "sqshrun\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2"
>   [(set_attr "type" "neon_shift_imm_narrow_q")]
> @@ -7629,38 +7612,31 @@
> 
> (define_expand "aarch64_sqshrun_n<mode>"
>   [(set (match_operand:<VNARROWQ> 0 "register_operand")
> - (truncate:<VNARROWQ>
> -  (smin:VQN
> -    (smax:VQN
> -      (ashiftrt:VQN
> - (match_operand:VQN 1 "register_operand")
> - (match_operand:SI 2 "aarch64_simd_shift_imm_offset_<vn_mode>"))
> -      (match_dup 3))
> -    (match_dup 4))))]
> + (us_truncate:<VNARROWQ>
> +  (smax:VQN
> +    (ashiftrt:VQN
> +      (match_operand:VQN 1 "register_operand")
> +      (match_operand:SI 2 "aarch64_simd_shift_imm_offset_<vn_mode>"))
> +    (match_dup 3))))]
>   "TARGET_SIMD"
>   {
>     operands[2] = aarch64_simd_gen_const_vector_dup (<MODE>mode,
> INTVAL (operands[2]));
>     operands[3] = CONST0_RTX (<MODE>mode);
> -    operands[4]
> -      = aarch64_simd_gen_const_vector_dup (<MODE>mode,
> - GET_MODE_MASK (GET_MODE_INNER (<VNARROWQ>mode)));
>   }
> )
> 
> (define_insn "*aarch64_sqrshrun_n<mode>_insn<vczle><vczbe>"
>   [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
> - (truncate:<VNARROWQ>
> -  (smin:<V2XWIDE>
> -    (smax:<V2XWIDE>
> -      (ashiftrt:<V2XWIDE>
> - (plus:<V2XWIDE>
> -  (sign_extend:<V2XWIDE>
> -    (match_operand:VQN 1 "register_operand" "w"))
> -  (match_operand:<V2XWIDE> 3 "aarch64_int_rnd_operand"))
> - (match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> -      (match_operand:<V2XWIDE> 4 "aarch64_simd_imm_zero"))
> -    (match_operand:<V2XWIDE> 5 "aarch64_simd_umax_quarter_mode"))))]
> + (us_truncate:<VNARROWQ>
> +  (smax:<V2XWIDE>
> +    (ashiftrt:<V2XWIDE>
> +      (plus:<V2XWIDE>
> + (sign_extend:<V2XWIDE>
> +  (match_operand:VQN 1 "register_operand" "w"))
> + (match_operand:<V2XWIDE> 3 "aarch64_int_rnd_operand"))
> +      (match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> +    (match_operand:<V2XWIDE> 4 "aarch64_simd_imm_zero"))))]
>   "TARGET_SIMD
>    && aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
>   "sqrshrun\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2"
> @@ -7703,17 +7679,15 @@
> 
> (define_expand "aarch64_sqrshrun_n<mode>"
>   [(set (match_operand:<VNARROWQ> 0 "register_operand")
> - (truncate:<VNARROWQ>
> -  (smin:<V2XWIDE>
> -    (smax:<V2XWIDE>
> -      (ashiftrt:<V2XWIDE>
> - (plus:<V2XWIDE>
> -  (sign_extend:<V2XWIDE>
> -    (match_operand:VQN 1 "register_operand"))
> -  (match_dup 3))
> - (match_operand:SI 2 "aarch64_simd_shift_imm_offset_<vn_mode>"))
> -      (match_dup 4))
> -    (match_dup 5))))]
> + (us_truncate:<VNARROWQ>
> +  (smax:<V2XWIDE>
> +    (ashiftrt:<V2XWIDE>
> +      (plus:<V2XWIDE>
> + (sign_extend:<V2XWIDE>
> +  (match_operand:VQN 1 "register_operand"))
> + (match_dup 3))
> +      (match_operand:SI 2 "aarch64_simd_shift_imm_offset_<vn_mode>"))
> +    (match_dup 4))))]
>   "TARGET_SIMD"
>   {
>     int prec = GET_MODE_UNIT_PRECISION (<V2XWIDE>mode);
> @@ -7722,9 +7696,6 @@
>     operands[3] = gen_const_vec_duplicate (<V2XWIDE>mode, operands[3]);
>     operands[2] = gen_const_vec_duplicate (<MODE>mode, operands[2]);
>     operands[4] = CONST0_RTX (<V2XWIDE>mode);
> -    operands[5]
> -      = gen_int_mode (GET_MODE_MASK (GET_MODE_INNER (<VNARROWQ>mode)), 
> DImode);
> -    operands[5] = gen_const_vec_duplicate (<V2XWIDE>mode, operands[5]);
>   }
> )
> 
> @@ -7854,14 +7825,12 @@
>   [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
> (vec_concat:<VNARROWQ2>
>  (match_operand:<VNARROWQ> 1 "register_operand" "0")
> -  (truncate:<VNARROWQ>
> -    (smin:VQN
> -      (smax:VQN
> - (ashiftrt:VQN
> -  (match_operand:VQN 2 "register_operand" "w")
> -  (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> - (match_operand:VQN 4 "aarch64_simd_imm_zero"))
> -      (match_operand:VQN 5 "aarch64_simd_umax_half_mode")))))]
> +  (us_truncate:<VNARROWQ>
> +    (smax:VQN
> +      (ashiftrt:VQN
> + (match_operand:VQN 2 "register_operand" "w")
> + (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> +      (match_operand:VQN 4 "aarch64_simd_imm_zero")))))]
>   "TARGET_SIMD && !BYTES_BIG_ENDIAN"
>   "sqshrun2\t%<vn2>0.<V2ntype>, %<v>2.<Vtype>, %3"
>   [(set_attr "type" "neon_shift_imm_narrow_q")]
> @@ -7870,14 +7839,12 @@
> (define_insn "aarch64_sqshrun2_n<mode>_insn_be"
>   [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
> (vec_concat:<VNARROWQ2>
> -  (truncate:<VNARROWQ>
> -    (smin:VQN
> -      (smax:VQN
> - (ashiftrt:VQN
> -  (match_operand:VQN 2 "register_operand" "w")
> -  (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> - (match_operand:VQN 4 "aarch64_simd_imm_zero"))
> -      (match_operand:VQN 5 "aarch64_simd_umax_half_mode")))
> +  (us_truncate:<VNARROWQ>
> +    (smax:VQN
> +      (ashiftrt:VQN
> + (match_operand:VQN 2 "register_operand" "w")
> + (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> +      (match_operand:VQN 4 "aarch64_simd_imm_zero")))
>  (match_operand:<VNARROWQ> 1 "register_operand" "0")))]
>   "TARGET_SIMD && BYTES_BIG_ENDIAN"
>   "sqshrun2\t%<vn2>0.<V2ntype>, %<v>2.<Vtype>, %3"
> @@ -7894,17 +7861,14 @@
>     operands[3] = aarch64_simd_gen_const_vector_dup (<MODE>mode,
> INTVAL (operands[3]));
>     rtx zeros = CONST0_RTX (<MODE>mode);
> -    rtx half_umax
> -      = aarch64_simd_gen_const_vector_dup (<MODE>mode,
> - GET_MODE_MASK (GET_MODE_INNER (<VNARROWQ>mode)));
>     if (BYTES_BIG_ENDIAN)
>       emit_insn (gen_aarch64_sqshrun2_n<mode>_insn_be (operands[0],
> operands[1], operands[2], operands[3],
> - zeros, half_umax));
> + zeros));
>     else
>       emit_insn (gen_aarch64_sqshrun2_n<mode>_insn_le (operands[0],
> operands[1], operands[2], operands[3],
> - zeros, half_umax));
> + zeros));
>     DONE;
>   }
> )
> @@ -7913,17 +7877,15 @@
>   [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
> (vec_concat:<VNARROWQ2>
>  (match_operand:<VNARROWQ> 1 "register_operand" "0")
> -  (truncate:<VNARROWQ>
> -    (smin:<V2XWIDE>
> -      (smax:<V2XWIDE>
> - (ashiftrt:<V2XWIDE>
> -  (plus:<V2XWIDE>
> -    (sign_extend:<V2XWIDE>
> -      (match_operand:VQN 2 "register_operand" "w"))
> -    (match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
> -  (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> - (match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
> -      (match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))))]
> +  (us_truncate:<VNARROWQ>
> +    (smax:<V2XWIDE>
> +      (ashiftrt:<V2XWIDE>
> + (plus:<V2XWIDE>
> +  (sign_extend:<V2XWIDE>
> +    (match_operand:VQN 2 "register_operand" "w"))
> +  (match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
> + (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> +      (match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero")))))]
>   "TARGET_SIMD && !BYTES_BIG_ENDIAN
>    && aarch64_const_vec_rnd_cst_p (operands[4], operands[3])"
>   "sqrshrun2\t%<vn2>0.<V2ntype>, %<v>2.<Vtype>, %3"
> @@ -7933,17 +7895,15 @@
> (define_insn "aarch64_sqrshrun2_n<mode>_insn_be"
>   [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
> (vec_concat:<VNARROWQ2>
> -  (truncate:<VNARROWQ>
> -    (smin:<V2XWIDE>
> -      (smax:<V2XWIDE>
> - (ashiftrt:<V2XWIDE>
> -  (plus:<V2XWIDE>
> -    (sign_extend:<V2XWIDE>
> -      (match_operand:VQN 2 "register_operand" "w"))
> -    (match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
> -  (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> - (match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
> -      (match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))
> +  (us_truncate:<VNARROWQ>
> +    (smax:<V2XWIDE>
> +      (ashiftrt:<V2XWIDE>
> + (plus:<V2XWIDE>
> +  (sign_extend:<V2XWIDE>
> +    (match_operand:VQN 2 "register_operand" "w"))
> +  (match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
> + (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
> +      (match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero")))
>  (match_operand:<VNARROWQ> 1 "register_operand" "0")))]
>   "TARGET_SIMD && BYTES_BIG_ENDIAN
>    && aarch64_const_vec_rnd_cst_p (operands[4], operands[3])"
> @@ -7963,18 +7923,15 @@
>     rtx rnd = immed_wide_int_const (rnd_wi, GET_MODE_INNER (<V2XWIDE>mode));
>     rnd = gen_const_vec_duplicate (<V2XWIDE>mode, rnd);
>     rtx zero = CONST0_RTX (<V2XWIDE>mode);
> -    rtx half_umax
> -      = aarch64_simd_gen_const_vector_dup (<V2XWIDE>mode,
> - GET_MODE_MASK (GET_MODE_INNER (<VNARROWQ>mode)));
>     operands[3] = gen_const_vec_duplicate (<MODE>mode, operands[3]);
>     if (BYTES_BIG_ENDIAN)
>       emit_insn (gen_aarch64_sqrshrun2_n<mode>_insn_be (operands[0],
> operands[1], operands[2], operands[3], rnd,
> - zero, half_umax));
> + zero));
>     else
>       emit_insn (gen_aarch64_sqrshrun2_n<mode>_insn_le (operands[0],
> operands[1], operands[2], operands[3], rnd,
> - zero, half_umax));
> + zero));
>     DONE;
>   }
> )
> diff --git a/gcc/config/aarch64/predicates.md 
> b/gcc/config/aarch64/predicates.md
> index 9d2613a9aee..308e3b264ef 100644
> --- a/gcc/config/aarch64/predicates.md
> +++ b/gcc/config/aarch64/predicates.md
> @@ -726,21 +726,6 @@
> 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_umax_quarter_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) / 4)) - 1,
> - (HOST_WIDE_INT_1U
> - << (GET_MODE_UNIT_BITSIZE (mode) / 4)) - 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)")))
> diff --git a/gcc/testsuite/gcc.target/aarch64/vect-sat-trunc-3.c 
> b/gcc/testsuite/gcc.target/aarch64/vect-sat-trunc-3.c
> new file mode 100644
> index 00000000000..5efe52e80bb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/vect-sat-trunc-3.c
> @@ -0,0 +1,41 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -march=armv8-a" } */
> +/* { dg-additional-options "-fno-schedule-insns -fno-schedule-insns2" } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +typedef __UINT16_TYPE__ u16;
> +
> +static inline u16
> +clip_u16 (int x)
> +{
> +  return (unsigned int) x > 65535u ? ((-x) >> 31) : x;
> +}
> +
> +/*
> +** clu:
> +** ...
> +** ldp q[0-9]+, q[0-9]+, \[x[0-9]+\]
> +** orr v[0-9]+\.4s, #1
> +** sqxtun v[0-9]+\.4h, v[0-9]+\.4s
> +** orr v[0-9]+\.4s, #1
> +** sqxtun v[0-9]+\.4h, v[0-9]+\.4s
> +** stp d[0-9]+, d[0-9]+, \[x[0-9]+\]
> +** ret
> +*/
> +void
> +clu (u16 *__restrict r, const int *__restrict x)
> +{
> +  for (int i = 0; i < 8; i++)
> +    r[i] = clip_u16 (x[i] | 1);
> +}
> +
> +/* The same in a variable-length loop.  */
> +void
> +clu_n (u16 *__restrict r, const int *__restrict x, int n)
> +{
> +  for (int i = 0; i < n; i++)
> +    r[i] = clip_u16 (x[i] | 1);
> +}
> +
> +/* { dg-final { scan-assembler-times {\tsqxtun\tv[0-9]+\.4h, v[0-9]+\.4s} 3 
> } } */
> +/* { dg-final { scan-assembler-not {\tuqxtn\tv[0-9]+\.4h, v[0-9]+\.4s} } } */
> -- 
> 2.55.0
> 

Reply via email to