[Bug tree-optimization/126981] [17 Regression] Wrong matching of saturating truncation
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Sep 3 13:57:03 GMT 2026
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126981
--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Kyrylo Tkachov <ktkachov@gcc.gnu.org>:
https://gcc.gnu.org/g:9e1c435c70a2ad4ca5285307b4a760f92c7a3426
commit r17-3899-g9e1c435c70a2ad4ca5285307b4a760f92c7a3426
Author: Kyrylo Tkachov <ktkachov@nvidia.com>
Date: Thu Sep 3 15:44:32 2026 +0200
aarch64: Use SVE2 SQXTNB and UQXTNB for saturating truncation
vect_recog_sat_trunc_pattern forms .SAT_TRUNC only when the target has
an sstrunc or ustrunc optab for the mode pair it selected. SVE2 has
SQXTNB and UQXTNB, but only exposes them through unspecs for the ACLE,
so a saturating truncation is vectorized as a minimum, or a minimum and
a maximum, feeding a truncating store.
The bottom forms write each result into the low half of its source
element, which is where the element of the unpacked result mode lives.
That holds when the source is itself unpacked, since the bits above each
source element are then don't-care on both sides. Extend VNARROWQ and
Vnarrowq to the SVE modes whose elements halve without changing the
number of lanes, and provide the two optabs over SVE_HSDI. The unpacked
source modes come out of that for free.
For
void
f (int8_t *__restrict d, const int16_t *__restrict s, int n)
{
for (int i = 0; i < n; ++i)
{
int16_t x = s[i];
int8_t t = (int8_t) x;
d[i] = -128 <= x && x <= 127 ? t : x < 0 ? -128 : 127;
}
}
the inner loop changes from
ld1h z31.h, p7/z, [x1, x3, lsl 1]
smin z31.h, z31.h, #127
smax z31.h, z31.h, #-128
st1b z31.h, p7, [x0, x3]
to
ld1h z31.h, p7/z, [x1, x3, lsl 1]
sqxtnb z31.b, z31.h
st1b z31.h, p7, [x0, x3]
This also makes the NARROW_CLIP form of .SAT_TRUNC reachable on
aarch64, so add a runtime test for the PR tree-optimization/126981
fix on top of the target independent one.
Bootstrapped and tested on aarch64-none-linux-gnu.
gcc/ChangeLog:
* config/aarch64/iterators.md (VNARROWQ, Vnarrowq): Add the SVE
modes whose elements halve without changing the number of lanes.
(Ventype): Add the unpacked SVE modes.
* config/aarch64/aarch64-sve2.md
(<sat_trunc_op>trunc<mode><Vnarrowq>2): New pattern.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/sve2/vect-sat-trunc-1.c: New test.
* gcc.target/aarch64/sve2/vect-sat-trunc-1_run.c: Likewise.
* gcc.target/aarch64/sve2/vect-sat-trunc-2.c: Likewise.
* gcc.target/aarch64/sve2/vect-sat-trunc-2_run.c: Likewise.
* gcc.target/aarch64/sve2/vect-sat-trunc-clip-1_run.c: Likewise.
Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
More information about the Gcc-bugs
mailing list