[gcc r17-3496] x86: Allow minus ones for Kn and standard constants for XMMn
"H.J. Lu via Gcc-cvs" <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:086b41669e64fda333cd91144070314912ae4ae9 commit r17-3496-g086b41669e64fda333cd91144070314912ae4ae9 Author: H.J. Lu <[email protected]> Date: Thu Aug 20 12:17:41 2026 +0800 x86: Allow minus ones for Kn and standard constants for XMMn Since we can load minus ones into a MASK register and standard SSE constants into a SSE register, allow them for MASK and SSE registers so that kxnor %k0, %k0, %k0 is used to load -1 into mask register, instead of loading from memory. gcc/ PR target/126959 * config/i386/i386.cc (ix86_preferred_reload_class): Allow minus ones for MASK register and standard SSE constants for SSE register. gcc/testsuite/ PR target/126959 * gcc.target/i386/pr126959-1a.c: New test. * gcc.target/i386/pr126959-1b.c: Likewise. * gcc.target/i386/pr126959-2a.c: Likewise. * gcc.target/i386/pr126959-2b.c: Likewise. Signed-off-by: H.J. Lu <[email protected]> Diff: --- gcc/config/i386/i386.cc | 23 +++++++----- gcc/testsuite/gcc.target/i386/pr126959-1a.c | 55 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr126959-1b.c | 36 +++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr126959-2a.c | 21 +++++++++++ gcc/testsuite/gcc.target/i386/pr126959-2b.c | 16 +++++++++ 5 files changed, 143 insertions(+), 8 deletions(-) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index dcfe4531f117..4b5380f0b056 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -21077,14 +21077,21 @@ ix86_preferred_reload_class (rtx x, reg_class_t regclass) if (x == CONST0_RTX (mode)) return regclass; - /* Force constants into memory if we are loading a (nonzero) constant into - an MMX, SSE or MASK register. This is because there are no MMX/SSE/MASK - instructions to load from a constant. */ - if (CONSTANT_P (x) - && (MAYBE_MMX_CLASS_P (regclass) - || MAYBE_SSE_CLASS_P (regclass) - || MAYBE_MASK_CLASS_P (regclass))) - return NO_REGS; + /* Force constants into memory if we are loading a non-zero constant + into an MMX, SSE or MASK register. This is because there are no + MMX/SSE/MASK instructions to load from a constant. Exceptions are + minus ones for MASK register and standard SSE constants for SSE + register. */ + if (CONSTANT_P (x)) + { + if (MAYBE_MMX_CLASS_P (regclass)) + return NO_REGS; + if (MAYBE_MASK_CLASS_P (regclass)) + return x == constm1_rtx ? regclass : NO_REGS; + if (MAYBE_SSE_CLASS_P (regclass)) + return (mode != VOIDmode && standard_sse_constant_p (x, mode) + ? regclass : NO_REGS); + } /* Floating-point constants need more complex checks. */ if (CONST_DOUBLE_P (x)) diff --git a/gcc/testsuite/gcc.target/i386/pr126959-1a.c b/gcc/testsuite/gcc.target/i386/pr126959-1a.c new file mode 100644 index 000000000000..a0c7b409cd63 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr126959-1a.c @@ -0,0 +1,55 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target *-*-* } {^\t?\.} } } */ + +/* +**func1: +**.LFB[0-9]+: +** .cfi_startproc +** kxnorb %k0, %k0, %k0 +** ret +** .cfi_endproc +**... +*/ + +void +func1 (void) +{ + unsigned char k = -1; + __asm volatile ("" : : "k" (k)); +} + +/* +**func2: +**.LFB[0-9]+: +** .cfi_startproc +** kxnorw %k0, %k0, %k0 +** ret +** .cfi_endproc +**... +*/ + +void +func2 (void) +{ + unsigned short k = -1; + __asm volatile ("" : : "k" (k)); +} + +/* +**func3: +**.LFB[0-9]+: +** .cfi_startproc +** kxnord %k0, %k0, %k0 +** ret +** .cfi_endproc +**... +*/ + +void +func3 (void) +{ + unsigned int k = -1; + __asm volatile ("" : : "k" (k)); +} diff --git a/gcc/testsuite/gcc.target/i386/pr126959-1b.c b/gcc/testsuite/gcc.target/i386/pr126959-1b.c new file mode 100644 index 000000000000..12b86f98e79e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr126959-1b.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -mtune=znver4" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target *-*-* } {^\t?\.} } } */ + +/* +**func1: +**.LFB[0-9]+: +** .cfi_startproc +** kxnorb %k0, %k0, %k0 +** ret +** .cfi_endproc +**... +*/ + +/* +**func2: +**.LFB[0-9]+: +** .cfi_startproc +** kxnorw %k0, %k0, %k0 +** ret +** .cfi_endproc +**... +*/ + +/* +**func3: +**.LFB[0-9]+: +** .cfi_startproc +** kxnord %k0, %k0, %k0 +** ret +** .cfi_endproc +**... +*/ + +#include "pr126959-1a.c" diff --git a/gcc/testsuite/gcc.target/i386/pr126959-2a.c b/gcc/testsuite/gcc.target/i386/pr126959-2a.c new file mode 100644 index 000000000000..3d350c85389a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr126959-2a.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -march=x86-64-v4" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target *-*-* } {^\t?\.} } } */ + +/* +**func: +**.LFB[0-9]+: +** .cfi_startproc +** kxnorq %k0, %k0, %k0 +** ret +** .cfi_endproc +**... +*/ + +void +func (void) +{ + unsigned long long k = -1; + __asm volatile ("" : : "k" (k)); +} diff --git a/gcc/testsuite/gcc.target/i386/pr126959-2b.c b/gcc/testsuite/gcc.target/i386/pr126959-2b.c new file mode 100644 index 000000000000..f4bd15bfbf8f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr126959-2b.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -march=x86-64-v4 -mtune=znver4" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target *-*-* } {^\t?\.} } } */ + +/* +**func: +**.LFB[0-9]+: +** .cfi_startproc +** kxnorq %k0, %k0, %k0 +** ret +** .cfi_endproc +**... +*/ + +#include "pr126959-2a.c"