[arm] PR target/83687: Fix invalid combination of VSUB + VABS into VABD
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Mon, 15 Jan 2018 11:56:03 +0000 (11:56 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Mon, 15 Jan 2018 11:56:03 +0000 (11:56 +0000)
commitd0b6b5a7b4932e68e82131ee2cde99d4fadacb9d
treeefbc2114605a98214bdcc6888a97a72004b7b692
parentc89f2d24685de5663523d328814541165a0d97c3
[arm] PR target/83687: Fix invalid combination of VSUB + VABS into VABD

In this wrong-code bug we combine a VSUB.I8 and a VABS.S8
into a VABD.S8 instruction . This combination is not valid
for integer operands because in the VABD instruction the semantics
are that the difference is computed in notionally infinite precision
and the absolute difference is computed on that, whereas for a
VSUB.I8 + VABS.S8 sequence the VSUB operation will perform any
wrapping that's needed for the 8-bit signed type before the VABS
gets its hands on it.

This leads to the wrong-code in the PR where the expected
sequence from the intrinsics:
VSUB + VABS of two vectors {-100, -100, -100...}, {100, 100, 100...}
gives a result of {56, 56, 56...} (-100 - 100)

but GCC optimises it into a single
VABD of {-100, -100, -100...}, {100, 100, 100...}
which produces a result of {200, 200, 200...}

The transformation is still valid for floating-point operands,
which is why it was added in the first place I believe (r178817)
but this patch disables it for integer operands.
The HFmode variants though only exist for TARGET_NEON_FP16INST, so
this patch adds the appropriate guards to the new mode iterator

Bootstrapped and tested on arm-none-linux-gnueabihf.

PR target/83687
* config/arm/iterators.md (VF): New mode iterator.
* config/arm/neon.md (neon_vabd<mode>_2): Use the above.
Remove integer-related logic from pattern.
(neon_vabd<mode>_3): Likewise.

* gcc.target/arm/neon-combine-sub-abs-into-vabd.c: Delete integer
tests.
* gcc.target/arm/pr83687.c: New test.

From-SVN: r256696
gcc/ChangeLog
gcc/config/arm/iterators.md
gcc/config/arm/neon.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/neon-combine-sub-abs-into-vabd.c
gcc/testsuite/gcc.target/arm/pr83687.c [new file with mode: 0644]