This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][ARM]Add earlyclobber modifier for neon_(vtrn, vuzp, vzip)<mode>_insn rtx pattern.
- From: Renlin Li <renlin dot li at arm dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: Ramana Radhakrishnan <Ramana dot Radhakrishnan at arm dot com>, Kyrill Tkachov <kyrylo dot tkachov at arm dot com>
- Date: Tue, 06 Oct 2015 18:27:43 +0100
- Subject: [PATCH][ARM]Add earlyclobber modifier for neon_(vtrn, vuzp, vzip)<mode>_insn rtx pattern.
- Authentication-results: sourceware.org; auth=none
Hi all,
Previously, the compiler will generate the following pattern, which will
cause an ICE during postreload pass. Meanwhile, the instruction itself
produces UNKNOWN result when the source and destination register are the
same according to ARM instruction manual. The same rule applies to vtrn
and vzip patterns.
(insn 50 71 106 3 (parallel [
(set (reg:V2SI 48 d16 [172])
(unspec:V2SI [
(reg:V2SI 48 d16 [172])
(reg:V2SI 48 d16 [172])
] UNSPEC_VUZP1))
(set (reg:V2SI 48 d16 [172])
(unspec:V2SI [
(reg:V2SI 48 d16 [172])
(reg:V2SI 48 d16 [172])
] UNSPEC_VUZP2))
]) /src/gcc/gcc/testsuite/gcc.dg/vect/pr37474.c:21 1991
{*neon_vuzpv2si_insn}
(nil))
The ICE is triggered when compiling gcc.dg/vect/pr37474.c using
arm-none-linux-gnueabihf toolchain.
Adding "&" modifier to operands[0] and operands[2] will explicitly
prevent those two register operands getting the same register.
I made the same changes to neon_vtrn<mode>_insn and neon_vzip<mode>_insn
pattern as well.
arm-none-linux-gnueabihf regression tests Okay. Okay to commit?
Regards,
Renlin Li
gcc/ChangeLog:
2015-10-06 Renlin Li <renlin.li@arm.com>
* config/arm/neon.md (neon_vuzp<mode>_insn): Add & modifier for
operands[0] and operands[2].
(neon_vtrn<mode>_insn): Likewise.
(neon_vzip<mode>_insn): Likewise.
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 2667866..e5a2b0f 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -4074,11 +4074,11 @@ if (BYTES_BIG_ENDIAN)
;; Note: Different operand numbering to handle tied registers correctly.
(define_insn "*neon_vtrn<mode>_insn"
- [(set (match_operand:VDQW 0 "s_register_operand" "=w")
+ [(set (match_operand:VDQW 0 "s_register_operand" "=&w")
(unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
(match_operand:VDQW 3 "s_register_operand" "2")]
UNSPEC_VTRN1))
- (set (match_operand:VDQW 2 "s_register_operand" "=w")
+ (set (match_operand:VDQW 2 "s_register_operand" "=&w")
(unspec:VDQW [(match_dup 1) (match_dup 3)]
UNSPEC_VTRN2))]
"TARGET_NEON"
@@ -4100,11 +4100,11 @@ if (BYTES_BIG_ENDIAN)
;; Note: Different operand numbering to handle tied registers correctly.
(define_insn "*neon_vzip<mode>_insn"
- [(set (match_operand:VDQW 0 "s_register_operand" "=w")
+ [(set (match_operand:VDQW 0 "s_register_operand" "=&w")
(unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
(match_operand:VDQW 3 "s_register_operand" "2")]
UNSPEC_VZIP1))
- (set (match_operand:VDQW 2 "s_register_operand" "=w")
+ (set (match_operand:VDQW 2 "s_register_operand" "=&w")
(unspec:VDQW [(match_dup 1) (match_dup 3)]
UNSPEC_VZIP2))]
"TARGET_NEON"
@@ -4126,11 +4126,11 @@ if (BYTES_BIG_ENDIAN)
;; Note: Different operand numbering to handle tied registers correctly.
(define_insn "*neon_vuzp<mode>_insn"
- [(set (match_operand:VDQW 0 "s_register_operand" "=w")
+ [(set (match_operand:VDQW 0 "s_register_operand" "=&w")
(unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
(match_operand:VDQW 3 "s_register_operand" "2")]
UNSPEC_VUZP1))
- (set (match_operand:VDQW 2 "s_register_operand" "=w")
+ (set (match_operand:VDQW 2 "s_register_operand" "=&w")
(unspec:VDQW [(match_dup 1) (match_dup 3)]
UNSPEC_VUZP2))]
"TARGET_NEON"