The zero movzx cost in Skylake and Ice Lake tunings makes CSE duplicate
DImode to TImode zero extensions into stores, preventing STV conversion.
Use the add cost for standalone extensions when optimizing for speed,
since clearing the upper word requires an extra instruction.
SImode to DImode zero extensions in 32-bit mode are left unchanged,
since treating zero_extend as free appears to produce better 32-bit
code.
Bootstrapped and retested on x86_64-pc-linux-gnu{-m32,}.
Ok for trunk?
gcc/ChangeLog:
PR target/127020
* config/i386/i386.cc (ix86_rtx_costs): Use the add cost for
standalone DImode to TImode zero extensions when optimizing for
speed.
gcc/testsuite/ChangeLog:
PR target/127020
* gcc.target/i386/pr127020.c: New test.
Co-authored-by: H.J. Lu <[email protected]>
---
gcc/config/i386/i386.cc | 8 ++++++++
gcc/testsuite/gcc.target/i386/pr127020.c | 16 ++++++++++++++++
2 files changed, 24 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/i386/pr127020.c
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index a8edf28f687..2291ec7a88e 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -22982,6 +22982,14 @@ ix86_rtx_costs (rtx x, machine_mode mode, int
outer_code_i, int opno,
if (TARGET_64BIT && mode == DImode
&& GET_MODE (XEXP (x, 0)) == SImode)
*total = 1;
+ /* A DImode to TImode zero extension needs an extra instruction to
+ clear the upper word; don't let a zero movzx cost make it look
+ free, or CSE copies it into every TImode store and STV can no
+ longer share one vector register. */
+ else if (speed && TARGET_64BIT && mode == TImode
+ && outer_code == SET
+ && GET_MODE (XEXP (x, 0)) == DImode)
+ *total = cost->add;
else if (TARGET_ZERO_EXTEND_WITH_AND)
*total = cost->add;
else
diff --git a/gcc/testsuite/gcc.target/i386/pr127020.c
b/gcc/testsuite/gcc.target/i386/pr127020.c
new file mode 100644
index 00000000000..4adc17cfc4c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr127020.c
@@ -0,0 +1,16 @@
+/* PR target/127020 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -msse4.1 -mtune=cascadelake -mstv -mno-stackrealign" } */
+
+extern __int128 m0, m1, m2, m3;
+
+void
+foo (unsigned long x)
+{
+ m0 = x;
+ m1 = x;
+ m2 = x;
+ m3 = x;
+}
+
+/* { dg-final { scan-assembler-times "(movaps|vmovdqa)" 4 } } */
--
2.34.1