Go to file
Jakub Jelinek a7b626d98a i386: Fix up @xorsign<mode>3_1 [PR102224]
As the testcase shows, we miscompile @xorsign<mode>3_1 if both input
operands are in the same register, because the splitter overwrites op1
before with op1 & mask before using op0.

For dest = xorsign op0, op0 we can actually simplify it from
dest = (op0 & mask) ^ op0 to dest = op0 & ~mask (aka abs).

The expander change is an optimization improvement, if we at expansion
time know it is xorsign op0, op0, we can emit abs right away and get better
code through that.

The @xorsign<mode>3_1 is a fix for the case where xorsign wouldn't be known
to have same operands during expansion, but during RTL optimizations they
would appear.  For non-AVX we need to use earlyclobber, we require
dest and op1 to be the same but op0 must be different because we overwrite
op1 first.  For AVX the constraints ensure that at most 2 of the 3 operands
may be the same register and if both inputs are the same, handles that case.
This case can be easily tested with the xorsign<mode>3 expander change
reverted.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Thinking about it more this morning, while this patch fixes the problems
revealed in the testcase, the recent PR89984 change was buggy too, but
perhaps that can be fixed incrementally.  Because for AVX the new code
destructively modifies op1.  If that is different from dest, say on:
float
foo (float x, float y)
{
  return x * __builtin_copysignf (1.0f, y) + y;
}
then we get after RA:
(insn 8 7 9 2 (set (reg:SF 20 xmm0 [orig:82 _2 ] [82])
        (unspec:SF [
                (reg:SF 20 xmm0 [88])
                (reg:SF 21 xmm1 [89])
                (mem/u/c:V4SF (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0  S16 A128])
            ] UNSPEC_XORSIGN)) "hohoho.c":4:12 649 {xorsignsf3_1}
     (nil))
(insn 9 8 15 2 (set (reg:SF 20 xmm0 [87])
        (plus:SF (reg:SF 20 xmm0 [orig:82 _2 ] [82])
            (reg:SF 21 xmm1 [89]))) "hohoho.c":4:44 1021 {*fop_sf_comm}
     (nil))
but split the xorsign into:
        vandps  .LC0(%rip), %xmm1, %xmm1
        vxorps  %xmm0, %xmm1, %xmm0
and then the addition:
        vaddss  %xmm1, %xmm0, %xmm0
which means we miscompile it - instead of adding y in the end we add
__builtin_copysignf (0.0f, y).
So, wonder if we don't want instead in addition to the &Yv <- Yv, 0
alternative (enabled for both pre-AVX and AVX as in this patch) the
&Yv <- Yv, Yv where destination must be different from inputs and another
Yv <- Yv, Yv where it can be the same but then need a match_scratch
(with X for the other alternatives and =Yv for the last one).
That way we'd always have a safe register we can store the op1 & mask
value into, either the destination (in the first alternative known to
be equal to op1 which is needed for non-AVX but ok for AVX too), in the
second alternative known to be different from both inputs and in the third
which could be used for those
float bar (float x, float y) { return x * __builtin_copysignf (1.0f, y); }
cases where op1 is naturally xmm1 and dest == op0 naturally xmm0 we'd use
some other register like xmm2.

2021-09-08  Jakub Jelinek  <jakub@redhat.com>

	PR target/102224
	* config/i386/i386.md (xorsign<mode>3): If operands[1] is equal to
	operands[2], emit abs<mode>2 instead.
	(@xorsign<mode>3_1): Add early-clobbers for output operand, enable
	first alternative even for avx, add another alternative with
	=&Yv <- 0, Yv, Yvm constraints.
	* config/i386/i386-expand.c (ix86_split_xorsign): If op0 is equal
	to op1, emit vpandn instead.

	* gcc.dg/pr102224.c: New test.
	* gcc.target/i386/avx-pr102224.c: New test.
2021-09-08 11:25:31 +02:00
c++tools Daily bump. 2021-07-22 00:16:46 +00:00
config Daily bump. 2021-08-19 00:16:42 +00:00
contrib Daily bump. 2021-09-07 00:16:34 +00:00
fixincludes Daily bump. 2021-08-31 00:16:50 +00:00
gcc i386: Fix up @xorsign<mode>3_1 [PR102224] 2021-09-08 11:25:31 +02:00
gnattools
gotools
include Daily bump. 2021-08-24 00:17:00 +00:00
INSTALL
intl
libada
libatomic Daily bump. 2021-07-22 00:16:46 +00:00
libbacktrace Daily bump. 2021-08-14 00:16:29 +00:00
libcc1 Daily bump. 2021-08-18 00:16:48 +00:00
libcody
libcpp Daily bump. 2021-09-02 00:16:59 +00:00
libdecnumber
libffi Daily bump. 2021-08-31 00:16:50 +00:00
libgcc Daily bump. 2021-09-07 00:16:34 +00:00
libgfortran Daily bump. 2021-09-08 00:16:23 +00:00
libgo runtime: use hash32, not hash64, for amd64p32, mips64p32, mips64p32le 2021-09-07 15:05:11 -07:00
libgomp Daily bump. 2021-09-08 00:16:23 +00:00
libiberty Daily bump. 2021-09-02 00:16:59 +00:00
libitm
libobjc
liboffloadmic
libphobos Daily bump. 2021-09-02 00:16:59 +00:00
libquadmath
libsanitizer Daily bump. 2021-08-12 00:16:28 +00:00
libssp
libstdc++-v3 Daily bump. 2021-09-03 00:16:33 +00:00
libvtv
lto-plugin
maintainer-scripts
zlib
.dir-locals.el dir-locals: Use https for bug references 2021-07-20 11:40:34 +01:00
.gitattributes
.gitignore
ABOUT-NLS
ar-lib
ChangeLog Daily bump. 2021-09-02 00:16:59 +00:00
ChangeLog.jit
ChangeLog.tree-ssa
compile
config-ml.in
config.guess
config.rpath
config.sub
configure
configure.ac
COPYING
COPYING3
COPYING3.LIB
COPYING.LIB
COPYING.RUNTIME
depcomp
install-sh
libtool-ldflags
libtool.m4
lt~obsolete.m4
ltgcc.m4 libtool.m4: Update to libtool 2.2.6. 2008-09-26 16:21:02 +00:00
ltmain.sh
ltoptions.m4
ltsugar.m4
ltversion.m4
MAINTAINERS MAINTAINERS: Add YunQiang Su for write after approval 2021-09-01 18:19:12 +08:00
Makefile.def gdb: Add a dependency between gdb and libbacktrace 2021-08-31 10:00:22 +01:00
Makefile.in gdb: Add a dependency between gdb and libbacktrace 2021-08-31 10:00:22 +01:00
Makefile.tpl configure: Allow host fragments to react to --enable-host-shared. 2021-08-18 19:46:32 +01:00
missing
mkdep
mkinstalldirs
move-if-change
multilib.am
README
symlink-tree
test-driver
ylwrap

This directory contains the GNU Compiler Collection (GCC).

The GNU Compiler Collection is free software.  See the files whose
names start with COPYING for copying permission.  The manuals, and
some of the runtime libraries, are under different terms; see the
individual source files for details.

The directory INSTALL contains copies of the installation information
as HTML and plain text.  The source of this information is
gcc/doc/install.texi.  The installation information includes details
of what is included in the GCC sources and what files GCC installs.

See the file gcc/doc/gcc.texi (together with other files that it
includes) for usage and porting information.  An online readable
version of the manual is in the files gcc/doc/gcc.info*.

See http://gcc.gnu.org/bugs/ for how to report bugs usefully.

Copyright years on GCC source files may be listed using range
notation, e.g., 1987-2012, indicating that every year in the range,
inclusive, is a copyrightable year that could otherwise be listed
individually.