On 9/16/26 9:16 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>
An arithmetic right shift preserves its input sign. The range test and
conversion can therefore use the shifted value while the saturation value
uses the original input:
shifted = x >> 8;
range = (unsigned int) shifted + 32768;
out = range > 65535
? (short int) (x >> 31) ^ 32767 : (short int) shifted;
This is equivalent to .SAT_TRUNC (shifted). Recognize a
precision-minus-one sign shift and allow the saturation value to use the
original input sign. The sign shift produces zero or minus one, so its
optional signed conversion can narrow or extend the value exactly.
Require the data shift to be a constant smaller than the input precision.
Require the range type to be at least as wide as the shifted value and the
output type, so the conversion and clamp constants do not lose bits.
With AArch64 -O2 -march=armv8-a -fopenmp-simd:
before:
ldp d0, d30, [x1]
movi v27.2s, 0x80, lsl 8
movi v25.2s, 0xff, msl 8
mvni v31.4h, 0x80, lsl 8
sshr v29.2s, v0.2s, 8
sshr v28.2s, v30.2s, 8
cmlt v0.2s, v0.2s, #0
cmlt v30.2s, v30.2s, #0
add v26.2s, v29.2s, v27.2s
add v27.2s, v28.2s, v27.2s
uzp1 v30.4h, v0.4h, v30.4h
uzp1 v28.4h, v29.4h, v28.4h
cmhi v26.2s, v26.2s, v25.2s
cmhi v27.2s, v27.2s, v25.2s
eor v31.8b, v30.8b, v31.8b
uzp1 v27.4h, v26.4h, v27.4h
bit v28.8b, v31.8b, v27.8b
str d28, [x0]
ret
after:
ldr q31, [x1]
sqshrn v31.4h, v31.4s, 8
str d31, [x0]
ret
The vector sequence becomes one SQSHRN. Runtime tests cover valid and
wrapping forms. Target tests cover valid forms, rejected forms, and the
related signed saturating addition and subtraction forms.
Bootstrapped and tested on aarch64-none-linux-gnu.
Tested on x86_64-pc-linux-gnu.
Ok for trunk?
Changes since v3:
- Rebase on current trunk.
gcc/ChangeLog:
* match-sat-alu.pd (signed_integer_sat_val): Recognize an arithmetic
sign shift.
(signed_integer_sat_trunc): Use signed_integer_sat_val in the existing
form. Recognize a shifted value with an equivalent pre-shift sign
source.
gcc/testsuite/ChangeLog:
* gcc.dg/vect/vect-sat-trunc-shift-sign-source-1.c: New test.
* gcc.target/aarch64/sat_s_val_ashr-1.c: Likewise.
* gcc.target/aarch64/vect-sat-trunc-shift-sign-source-1.c: Likewise.
* gcc.target/aarch64/vect-sat-trunc-shift-sign-source-negative-1.c:
Likewise.
Signed-off-by: Kyrylo Tkachov <[email protected]>
OK. This is starting to get fairly hard to read. But I think this and
patch #2 of the series are the worst (which is why they're getting
reviewed last). Don't be afraid of comments in the conditionals
themselves -- they speak to intent and ease the burden on any future
reader.
Jeff