> 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 <ramana.radhakrish...@linaro.org> * 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. --- 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")] ) -- 1.7.4.1