https://gcc.gnu.org/g:0022064649d0ec40e97df24279c48842e278fedc
commit r15-841-g0022064649d0ec40e97df24279c48842e278fedc Author: Levy Hsu <ad...@levyhsu.com> Date: Tue May 21 12:47:21 2024 +0930 x86: Fix Logical Shift Issue in expand_vec_perm_psrlw_psllw_por [PR115146] Replaced arithmetic shifts with logical shifts in expand_vec_perm_psrlw_psllw_por to avoid sign bit extension issues. Also corrected gen_vlshrv8hi3 to gen_lshrv8hi3 and gen_vashlv8hi3 to gen_ashlv8hi3. Co-authored-by: H.J. Lu <hjl.to...@gmail.com> gcc/ChangeLog: PR target/115146 * config/i386/i386-expand.cc (expand_vec_perm_psrlw_psllw_por): Replace arithmatic shift gen_ashrv4hi3 with logic shift gen_lshrv4hi3. Replace gen_vlshrv8hi3 with gen_lshrv8hi3 and gen_vashlv8hi3 with gen_ashlv8hi3. gcc/testsuite/ChangeLog: PR target/115146 * g++.target/i386/pr107563-a.C: Append '-mno-sse3' to compile option to avoid test failure on hosts with SSE3 support. * g++.target/i386/pr107563-b.C: Append '-mno-sse3' to compile option to avoid test failure on hosts with SSE3 support. * gcc.target/i386/pr115146.c: New test. Diff: --- gcc/config/i386/i386-expand.cc | 6 ++--- gcc/testsuite/g++.target/i386/pr107563-a.C | 4 ++-- gcc/testsuite/g++.target/i386/pr107563-b.C | 2 +- gcc/testsuite/gcc.target/i386/pr115146.c | 38 ++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index ec402a78a09..215a998fc26 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -22055,14 +22055,14 @@ expand_vec_perm_psrlw_psllw_por (struct expand_vec_perm_d *d) if (!TARGET_MMX_WITH_SSE) return false; mode = V4HImode; - gen_shr = gen_ashrv4hi3; + gen_shr = gen_lshrv4hi3; gen_shl = gen_ashlv4hi3; gen_or = gen_iorv4hi3; break; case E_V16QImode: mode = V8HImode; - gen_shr = gen_vlshrv8hi3; - gen_shl = gen_vashlv8hi3; + gen_shr = gen_lshrv8hi3; + gen_shl = gen_ashlv8hi3; gen_or = gen_iorv8hi3; break; default: return false; diff --git a/gcc/testsuite/g++.target/i386/pr107563-a.C b/gcc/testsuite/g++.target/i386/pr107563-a.C index 605c1bdf814..c1c332bb948 100755 --- a/gcc/testsuite/g++.target/i386/pr107563-a.C +++ b/gcc/testsuite/g++.target/i386/pr107563-a.C @@ -1,8 +1,8 @@ /* PR target/107563.C */ /* { dg-do compile { target { ! ia32 } } } */ -/* { dg-options "-std=c++2b -O3 -msse2" } */ +/* { dg-options "-std=c++2b -O3 -msse2 -mno-sse3" } */ /* { dg-final { scan-assembler-times "psllw" 1 } } */ -/* { dg-final { scan-assembler-times "psraw" 1 } } */ +/* { dg-final { scan-assembler-times "psrlw" 1 } } */ /* { dg-final { scan-assembler-times "por" 1 } } */ using temp_vec_type2 [[__gnu__::__vector_size__(8)]] = char; diff --git a/gcc/testsuite/g++.target/i386/pr107563-b.C b/gcc/testsuite/g++.target/i386/pr107563-b.C index 0ce3e8263bb..d5cc0300f46 100755 --- a/gcc/testsuite/g++.target/i386/pr107563-b.C +++ b/gcc/testsuite/g++.target/i386/pr107563-b.C @@ -1,5 +1,5 @@ /* PR target/107563.C */ -/* { dg-options "-std=c++2b -O3 -msse2" } */ +/* { dg-options "-std=c++2b -O3 -msse2 -mno-sse3" } */ /* { dg-final { scan-assembler-times "psllw" 1 } } */ /* { dg-final { scan-assembler-times "psrlw" 1 } } */ /* { dg-final { scan-assembler-times "por" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr115146.c b/gcc/testsuite/gcc.target/i386/pr115146.c new file mode 100755 index 00000000000..b7706bf391c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr115146.c @@ -0,0 +1,38 @@ +/* { dg-do run { target sse2_runtime } } */ +/* { dg-options "-O2 -msse2" } */ + +typedef unsigned char v8qi __attribute__((vector_size (8))); + +v8qi res, a; + +void __attribute__((noipa)) +foo (void) +{ + res = __builtin_shufflevector(a, a, 1, 0, 3, 2, 5, 4, 7, 6); +} + +void +comp (v8qi a, v8qi b, int n) +{ + for (unsigned i = 0; i < n; ++i) + if ((a)[i] != (b)[i]) + __builtin_abort (); +} + +#define E0 140 +#define E1 141 +#define E2 142 +#define E3 143 +#define E4 144 +#define E5 145 +#define E6 146 +#define E7 147 + +int main() +{ + a = (v8qi) { E0, E1, E2, E3, E4, E5, E6, E7 }; + foo (); + comp (res, ((v8qi) { E1, E0, E3, E2, E5, E4, E7, E6 }), 8); + return 0; +} +