aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamar Christina <tamar.christina@arm.com>2023-10-02 11:51:10 +0100
committerTamar Christina <tamar.christina@arm.com>2023-10-02 11:51:10 +0100
commitf2b23a59cbe46a7839811cbeb962c2081b329b73 (patch)
tree29b7f71d0b461f6c22a0012f6ca69c4b20543998
parenta35ab1c1a3d04c28519a062fedfebda818b927a4 (diff)
downloadgcc-f2b23a59cbe46a7839811cbeb962c2081b329b73.zip
gcc-f2b23a59cbe46a7839811cbeb962c2081b329b73.tar.gz
gcc-f2b23a59cbe46a7839811cbeb962c2081b329b73.tar.bz2
AArch64: Fix scalar xorsign lowering
In GCC-9 our scalar xorsign pattern broke and we didn't notice it because the testcase was not strong enough. With this commit 8d2d39587d941a40f25ea0144cceb677df115040 is the first bad commit commit 8d2d39587d941a40f25ea0144cceb677df115040 Author: Segher Boessenkool <segher@kernel.crashing.org> Date: Mon Oct 22 22:23:39 2018 +0200 combine: Do not combine moves from hard registers combine started introducing useless moves on hard registers, when one of the arguments to our scalar xorsign is a hardreg we get an additional move inserted. This leads to combine forming an AND with the immediate inside and using the superflous move to do the r->w move, instead of what we wanted before which was for the `and` to be a vector and and have reload pick the right alternative. To fix this the patch just forces the use of the vector version directly and so combine has no chance to mess it up. gcc/ChangeLog: * config/aarch64/aarch64-simd.md (xorsign<mode>3): Renamed to.. (@xorsign<mode>3): ...This. * config/aarch64/aarch64.md (xorsign<mode>3): Renamed to... (@xorsign<mode>3): ..This and emit vectors directly * config/aarch64/iterators.md (VCONQ): Add SF and DF. gcc/testsuite/ChangeLog: * gcc.target/aarch64/xorsign.c:
-rw-r--r--gcc/config/aarch64/aarch64-simd.md2
-rw-r--r--gcc/config/aarch64/aarch64.md25
-rw-r--r--gcc/config/aarch64/iterators.md3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/xorsign.c5
4 files changed, 12 insertions, 23 deletions
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index f67eb70..e955691 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -500,7 +500,7 @@
}
)
-(define_expand "xorsign<mode>3"
+(define_expand "@xorsign<mode>3"
[(match_operand:VHSDF 0 "register_operand")
(match_operand:VHSDF 1 "register_operand")
(match_operand:VHSDF 2 "register_operand")]
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 6d0f072..f76c63b 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -6978,31 +6978,18 @@
;; EOR v0.8B, v0.8B, v3.8B
;;
-(define_expand "xorsign<mode>3"
+(define_expand "@xorsign<mode>3"
[(match_operand:GPF 0 "register_operand")
(match_operand:GPF 1 "register_operand")
(match_operand:GPF 2 "register_operand")]
"TARGET_SIMD"
{
-
- machine_mode imode = <V_INT_EQUIV>mode;
- rtx mask = gen_reg_rtx (imode);
- rtx op1x = gen_reg_rtx (imode);
- rtx op2x = gen_reg_rtx (imode);
-
- int bits = GET_MODE_BITSIZE (<MODE>mode) - 1;
- emit_move_insn (mask, GEN_INT (trunc_int_for_mode (HOST_WIDE_INT_M1U << bits,
- imode)));
-
- emit_insn (gen_and<v_int_equiv>3 (op2x, mask,
- lowpart_subreg (imode, operands[2],
- <MODE>mode)));
- emit_insn (gen_xor<v_int_equiv>3 (op1x,
- lowpart_subreg (imode, operands[1],
- <MODE>mode),
- op2x));
+ rtx tmp = gen_reg_rtx (<VCONQ>mode);
+ rtx op1 = lowpart_subreg (<VCONQ>mode, operands[1], <MODE>mode);
+ rtx op2 = lowpart_subreg (<VCONQ>mode, operands[2], <MODE>mode);
+ emit_insn (gen_xorsign3 (<VCONQ>mode, tmp, op1, op2));
emit_move_insn (operands[0],
- lowpart_subreg (<MODE>mode, op1x, imode));
+ lowpart_subreg (<MODE>mode, tmp, <VCONQ>mode));
DONE;
}
)
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 9398d71..2451d8c 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1428,7 +1428,8 @@
(V4HF "V8HF") (V8HF "V8HF")
(V2SF "V4SF") (V4SF "V4SF")
(V2DF "V2DF") (SI "V4SI")
- (HI "V8HI") (QI "V16QI")])
+ (HI "V8HI") (QI "V16QI")
+ (SF "V4SF") (DF "V2DF")])
;; Half modes of all vector modes.
(define_mode_attr VHALF [(V8QI "V4QI") (V16QI "V8QI")
diff --git a/gcc/testsuite/gcc.target/aarch64/xorsign.c b/gcc/testsuite/gcc.target/aarch64/xorsign.c
index 22c5829..dfb7ba7 100644
--- a/gcc/testsuite/gcc.target/aarch64/xorsign.c
+++ b/gcc/testsuite/gcc.target/aarch64/xorsign.c
@@ -79,8 +79,9 @@ check_l_neg_rev (long double x, long double y)
return __builtin_copysignl (-1.0, y) * x;
}
-/* { dg-final { scan-assembler "\[ \t\]?eor\[ \t\]?" } } */
-/* { dg-final { scan-assembler "\[ \t\]?and\[ \t\]?" } } */
+/* { dg-final { scan-assembler-times {eor\tv[0-9]+\.16b, v[0-9]+\.16b, v[0-9]+\.16b} 8 } } */
+/* { dg-final { scan-assembler-times {and\tv[0-9]+\.16b, v[0-9]+\.16b, v[0-9]+\.16b} 8 } } */
/* { dg-final { scan-assembler-not "copysign" } } */
+/* { dg-final { scan-assembler-not "fmov" } } */
/* { dg-final { scan-assembler-not "\[ \t\]?orr\[ \t\]?" } } */
/* { dg-final { scan-assembler-not "\[ \t\]?fmul\[ \t\]?" } } */