diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2012-11-29 17:51:40 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2012-11-29 17:51:40 +0000 |
commit | 28131dfe443772ac5e625914cc341f5be9f8bbc7 (patch) | |
tree | 0453edaac611d759afad05d1d702d72031be7ee3 /gcc/config/arm | |
parent | 1d029889864ac29255b9baeba93decb6afaf4bf9 (diff) | |
download | gcc-28131dfe443772ac5e625914cc341f5be9f8bbc7.tar.gz |
re PR target/55073 (Wrong Neon code generation at -O2 caused by -fschedule-insns)
PR target/55073
* arm/neon.md (neon_vtrn<mode>_internal): Split into expand
and insn patterns. Re-order insn arguments to tie inputs to
outputs.
(neon_vzip<mode>_internal): Likewise.
(neon_vuzp<mode>_internal): Likewise.
* gcc.target/arm/pr55073.C: New test.
From-SVN: r193943
Diffstat (limited to 'gcc/config/arm')
-rw-r--r-- | gcc/config/arm/neon.md | 69 |
1 files changed, 54 insertions, 15 deletions
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 8f84795334b..0822049a3e9 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -4411,16 +4411,29 @@ [(set_attr "neon_type" "neon_bp_3cycle")] ) -(define_insn "neon_vtrn<mode>_internal" +(define_expand "neon_vtrn<mode>_internal" + [(parallel + [(set (match_operand:VDQW 0 "s_register_operand" "") + (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "") + (match_operand:VDQW 2 "s_register_operand" "")] + UNSPEC_VTRN1)) + (set (match_operand:VDQW 3 "s_register_operand" "") + (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VTRN2))])] + "TARGET_NEON" + "" +) + +;; Note: Different operand numbering to handle tied registers correctly. +(define_insn "*neon_vtrn<mode>_insn" [(set (match_operand:VDQW 0 "s_register_operand" "=w") (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0") - (match_operand:VDQW 2 "s_register_operand" "w")] + (match_operand:VDQW 3 "s_register_operand" "2")] UNSPEC_VTRN1)) - (set (match_operand:VDQW 3 "s_register_operand" "=2") - (unspec:VDQW [(match_dup 1) (match_dup 2)] + (set (match_operand:VDQW 2 "s_register_operand" "=w") + (unspec:VDQW [(match_dup 1) (match_dup 3)] UNSPEC_VTRN2))] "TARGET_NEON" - "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>3" + "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2" [(set (attr "neon_type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_bp_simple") @@ -4438,16 +4451,29 @@ DONE; }) -(define_insn "neon_vzip<mode>_internal" +(define_expand "neon_vzip<mode>_internal" + [(parallel + [(set (match_operand:VDQW 0 "s_register_operand" "") + (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "") + (match_operand:VDQW 2 "s_register_operand" "")] + UNSPEC_VZIP1)) + (set (match_operand:VDQW 3 "s_register_operand" "") + (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VZIP2))])] + "TARGET_NEON" + "" +) + +;; Note: Different operand numbering to handle tied registers correctly. +(define_insn "*neon_vzip<mode>_insn" [(set (match_operand:VDQW 0 "s_register_operand" "=w") (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0") - (match_operand:VDQW 2 "s_register_operand" "w")] + (match_operand:VDQW 3 "s_register_operand" "2")] UNSPEC_VZIP1)) - (set (match_operand:VDQW 3 "s_register_operand" "=2") - (unspec:VDQW [(match_dup 1) (match_dup 2)] + (set (match_operand:VDQW 2 "s_register_operand" "=w") + (unspec:VDQW [(match_dup 1) (match_dup 3)] UNSPEC_VZIP2))] "TARGET_NEON" - "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>3" + "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2" [(set (attr "neon_type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_bp_simple") @@ -4465,16 +4491,29 @@ DONE; }) -(define_insn "neon_vuzp<mode>_internal" +(define_expand "neon_vuzp<mode>_internal" + [(parallel + [(set (match_operand:VDQW 0 "s_register_operand" "") + (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "") + (match_operand:VDQW 2 "s_register_operand" "")] + UNSPEC_VUZP1)) + (set (match_operand:VDQW 3 "s_register_operand" "") + (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VUZP2))])] + "TARGET_NEON" + "" +) + +;; Note: Different operand numbering to handle tied registers correctly. +(define_insn "*neon_vuzp<mode>_insn" [(set (match_operand:VDQW 0 "s_register_operand" "=w") (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0") - (match_operand:VDQW 2 "s_register_operand" "w")] + (match_operand:VDQW 3 "s_register_operand" "2")] UNSPEC_VUZP1)) - (set (match_operand:VDQW 3 "s_register_operand" "=2") - (unspec:VDQW [(match_dup 1) (match_dup 2)] + (set (match_operand:VDQW 2 "s_register_operand" "=w") + (unspec:VDQW [(match_dup 1) (match_dup 3)] UNSPEC_VUZP2))] "TARGET_NEON" - "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>3" + "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2" [(set (attr "neon_type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_bp_simple") |