On Mon, Aug 31, 2026 at 3:27 PM Hongtao Liu <[email protected]> wrote: > > On Mon, Aug 31, 2026 at 7:34 AM H.J. Lu <[email protected]> wrote: > > > > Add a gain of COSTS_N_INSNS (1) for pxor with TImode memory since it > > reduces one memory access vs 2 x xorq with DImode memory > > On Intel E-core and Zen5, xorq with DImode memory takes only 1 uop, on > intel P-core it takes 2 uops. So from uops perspective, on some > platforms we don't have extra gain for memory access(we already gain > COSTS_N_INSNS (1) for 1 por vs 2 xor). > if we need to account for 1 less memory access, all operations which > support memory_operand in their TImode patterns should be handled, not > only xor/ior?
Only pand/pior/pxor loads are relevant here. > even for xor/ior, why MEM_P(XEXP (src, 1)), although xorv1ti3 only > supports memory operand for XEXP (src, 1), but the xorti3_doubleword > pattern support memory_operand for XEXP (src, 0), and we're handling > TImode insn in compute_convert_gain. Here is the v2 patch to handle pand and check XEXP (src, 0). -- H.J. ---- Add a gain of COSTS_N_INSNS (1) for TImode pand/pior/pxor loads since they reduce one memory load, comparing against DImode and/ior/xor loads. gcc/ PR target/127020 * config/i386/i386-features.cc (timode_scalar_chain::compute_convert_gain): Add gain of COSTS_N_INSNS (1) for pand/pior/pxor loads. gcc/testsuite/ PR target/127020 * gcc.target/i386/sse2-stv-3.c: Adjusted. * gcc.target/i386/sse2-stv-8.c: New test. * gcc.target/i386/sse2-stv-9.c: Likewise.
From 70fa8a8d008cd8e442320568f4cf4e57a5599c22 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <[email protected]> Date: Tue, 25 Aug 2026 04:13:54 +0800 Subject: [PATCH v2] x86-64: Increase gain for TImode pand/pior/pxor loads Add a gain of COSTS_N_INSNS (1) for TImode pand/pior/pxor loads since they need one memory load, instead of two DImode and/ior/xor loads. gcc/ PR target/127020 * config/i386/i386-features.cc (timode_scalar_chain::compute_convert_gain): Add gain of COSTS_N_INSNS (1) for pand/pior/pxor loads. gcc/testsuite/ PR target/127020 * gcc.target/i386/sse2-stv-3.c: Adjusted. * gcc.target/i386/sse2-stv-8.c: New test. * gcc.target/i386/sse2-stv-9.c: Likewise. Signed-off-by: H.J. Lu <[email protected]> --- gcc/config/i386/i386-features.cc | 14 +++++++-- gcc/testsuite/gcc.target/i386/sse2-stv-3.c | 8 ++--- gcc/testsuite/gcc.target/i386/sse2-stv-8.c | 35 ++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/sse2-stv-9.c | 35 ++++++++++++++++++++++ 4 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/sse2-stv-8.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-stv-9.c diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index eb5f82e42cb..1d26aa0c336 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -1730,7 +1730,12 @@ timode_scalar_chain::compute_convert_gain () case AND: if (!MEM_P (dst)) - igain = COSTS_N_INSNS (1); + { + igain = COSTS_N_INSNS (1); + if (MEM_P (XEXP (src, 0)) || MEM_P (XEXP (src, 1))) + /* One less load. */ + igain += COSTS_N_INSNS (1); + } if (CONST_SCALAR_INT_P (XEXP (src, 1))) igain += timode_immed_const_gain (XEXP (src, 1), bb); break; @@ -1745,7 +1750,12 @@ timode_scalar_chain::compute_convert_gain () break; } if (!MEM_P (dst)) - igain = COSTS_N_INSNS (1); + { + igain = COSTS_N_INSNS (1); + if (MEM_P (XEXP (src, 0)) || MEM_P (XEXP (src, 1))) + /* One less load. */ + igain += COSTS_N_INSNS (1); + } if (CONST_SCALAR_INT_P (XEXP (src, 1))) igain += timode_immed_const_gain (XEXP (src, 1), bb); break; diff --git a/gcc/testsuite/gcc.target/i386/sse2-stv-3.c b/gcc/testsuite/gcc.target/i386/sse2-stv-3.c index 0a638013aed..9f3210a9adb 100644 --- a/gcc/testsuite/gcc.target/i386/sse2-stv-3.c +++ b/gcc/testsuite/gcc.target/i386/sse2-stv-3.c @@ -25,7 +25,7 @@ void foo_fun() z = (fun() ^ a ^ b ^ c); } -/* { dg-final { scan-assembler-times "punpcklqdq" 2 } } */ -/* { dg-final { scan-assembler-times "movhlps" 1 } } */ -/* { dg-final { scan-assembler-times "pxor" 9 } } */ -/* { dg-final { scan-assembler-times "xorq" 8 } } */ +/* { dg-final { scan-assembler-times "punpcklqdq" 3 } } */ +/* { dg-final { scan-assembler-times "movhlps" 2 } } */ +/* { dg-final { scan-assembler-times "pxor" 13 } } */ +/* { dg-final { scan-assembler-not "xorq" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse2-stv-8.c b/gcc/testsuite/gcc.target/i386/sse2-stv-8.c new file mode 100644 index 00000000000..740ff302a71 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-stv-8.c @@ -0,0 +1,35 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse2 -mno-sse4 -mno-stackrealign" } */ + +extern __int128 a, b, c, z; + +__int128 fun(void); + +void +foo_in(__int128 x) +{ + z = x & a & b & c; +} + +__int128 +foo_out() +{ + return z & a & b & c; +} + +__int128 +foo_inout(__int128 x) +{ + return x & a & b & c & z; +} + +void +foo_fun() +{ + z = fun() & a & b & c; +} + +/* { dg-final { scan-assembler-times "punpcklqdq" 3 } } */ +/* { dg-final { scan-assembler-times "movhlps" 2 } } */ +/* { dg-final { scan-assembler-times "pand" 13 } } */ +/* { dg-final { scan-assembler-not "andq" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse2-stv-9.c b/gcc/testsuite/gcc.target/i386/sse2-stv-9.c new file mode 100644 index 00000000000..002ad761b08 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-stv-9.c @@ -0,0 +1,35 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse2 -mno-sse4 -mno-stackrealign" } */ + +extern __int128 a, b, c, z; + +__int128 fun(void); + +void +foo_in(__int128 x) +{ + z = x | a | b | c; +} + +__int128 +foo_out() +{ + return z | a | b | c; +} + +__int128 +foo_inout(__int128 x) +{ + return x | a | b | c | z; +} + +void +foo_fun() +{ + z = fun() | a | b | c; +} + +/* { dg-final { scan-assembler-times "punpcklqdq" 3 } } */ +/* { dg-final { scan-assembler-times "movhlps" 2 } } */ +/* { dg-final { scan-assembler-times "por" 13 } } */ +/* { dg-final { scan-assembler-not "orq" } } */ -- 2.55.0
