On 30/07/12 12:43, Ramana Radhakrishnan wrote:
>> Patch 1 fixes up the vaba and vabal patterns to use a canonical RTL
>> form with the first operand to the plus being the more complex one.
>
> This patch canonicalizes the instruction patterns for the
> vaba and vabal intrinsics so that the more complex operand
> to plus is the first operand. This prevents needless
> splitting in combine.
>
> For reference, this was found by the new test in gcc.target/neon/vaba*.c
> and gcc.target/neon/vabal*.c from patch #4.
>
>
> Ok ?
>
> regards,
> Ramana
>
> 2012-07-27 Ramana Radhakrishnan <[email protected]>
>
> * config/arm/neon.md (neon_vaba<mode>): Change to define_expand.
> (neon_vabal<mode>): Likewise.
> (neon_vaba_internal<mode>): New internal pattern.
> (neon_vabal_internal<mode>): New internal pattern.
In principle, this is OK. I think you could have achieved the same
effect more simply though by just re-ordering the RTL but keeping the
operand numbers the same.
R.
> ---
> gcc/config/arm/neon.md | 61 ++++++++++++++++++++++++++++++++++++-----------
> 1 files changed, 46 insertions(+), 15 deletions(-)
>
> diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
> index 7142c98..1ffbb7d 100644
> --- a/gcc/config/arm/neon.md
> +++ b/gcc/config/arm/neon.md
> @@ -2335,29 +2335,60 @@
> [(set_attr "neon_type" "neon_int_5")]
> )
>
> -(define_insn "neon_vaba<mode>"
> +(define_expand "neon_vaba<mode>"
> + [(match_operand:VDQIW 0 "s_register_operand" "")
> + (match_operand:VDQIW 1 "s_register_operand" "")
> + (match_operand:VDQIW 2 "s_register_operand" "")
> + (match_operand:VDQIW 3 "s_register_operand" "")
> + (match_operand:SI 4 "immediate_operand" "")]
> + "TARGET_NEON"
> + "{
> + emit_insn (gen_neon_vaba_internal<mode> (operands[0], operands[2],
> + operands[3], operands[4],
> + operands[1]));
> + DONE;
> + }"
> +)
> +
> +(define_insn "neon_vaba_internal<mode>"
> [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
> - (plus:VDQIW (match_operand:VDQIW 1 "s_register_operand" "0")
> - (unspec:VDQIW [(match_operand:VDQIW 2
> "s_register_operand" "w")
> - (match_operand:VDQIW 3 "s_register_operand"
> "w")
> - (match_operand:SI 4
> "immediate_operand" "i")]
> - UNSPEC_VABD)))]
> + (plus:VDQIW (unspec:VDQIW
> + [(match_operand:VDQIW 1 "s_register_operand" "w")
> + (match_operand:VDQIW 2 "s_register_operand" "w")
> + (match_operand:SI 3 "immediate_operand" "i")]
> UNSPEC_VABD)
> + (match_operand:VDQIW 4 "s_register_operand" "0")))]
> "TARGET_NEON"
> - "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
> + "vaba.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
> [(set (attr "neon_type")
> (if_then_else (match_test "<Is_d_reg>")
> (const_string "neon_vaba") (const_string
> "neon_vaba_qqq")))]
> )
>
> -(define_insn "neon_vabal<mode>"
> +(define_expand "neon_vabal<mode>"
> + [(match_operand:<V_widen> 0 "s_register_operand" "")
> + (match_operand:<V_widen> 1 "s_register_operand" "")
> + (match_operand:VW 2 "s_register_operand" "")
> + (match_operand:VW 3 "s_register_operand" "")
> + (match_operand:SI 4 "immediate_operand" "")]
> + "TARGET_NEON"
> + "{
> + emit_insn (gen_neon_vabal_internal<mode> (operands[0], operands[2],
> + operands[3], operands[4],
> + operands[1]));
> + DONE;
> + }"
> +)
> +
> +(define_insn "neon_vabal_internal<mode>"
> [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
> - (plus:<V_widen> (match_operand:<V_widen> 1 "s_register_operand" "0")
> - (unspec:<V_widen> [(match_operand:VW 2
> "s_register_operand" "w")
> - (match_operand:VW 3
> "s_register_operand" "w")
> - (match_operand:SI 4
> "immediate_operand" "i")]
> - UNSPEC_VABDL)))]
> - "TARGET_NEON"
> - "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
> + (plus:<V_widen> (unspec:<V_widen>
> + [(match_operand:VW 1 "s_register_operand" "w")
> + (match_operand:VW 2 "s_register_operand" "w")
> + (match_operand:SI 3 "immediate_operand" "i")]
> + UNSPEC_VABDL)
> + (match_operand:<V_widen> 4 "s_register_operand" "0")))]
> + "TARGET_NEON"
> + "vabal.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
> [(set_attr "neon_type" "neon_vaba")]
> )
>