Hi,
As subject, this patch rewrites [su]mlal_high_lane[q] Neon intrinsics to use
RTL builtins rather than inline assembly code, allowing for better scheduling
and optimization.
Regression tested and bootstrapped on aarch64-none-linux-gnu and
aarch64_be-none-elf - no issues.
Ok for master?
Thanks,
Jonathan
---
gcc/ChangeLog:
2021-02-02 Jonathan Wright
* config/aarch64/aarch64-simd-builtins.def: Add
[su]mlal_hi_lane[q] builtin generator macros.
* config/aarch64/aarch64-simd.md
(aarch64_mlal_hi_lane_insn): Define.
(aarch64_mlal_hi_lane): Define.
(aarch64_mlal_hi_laneq_insn): Define.
(aarch64_mlal_hi_laneq): Define.
* config/aarch64/arm_neon.h (vmlal_high_lane_s16): Use RTL
builtin instead of inline asm.
(vmlal_high_lane_s32): Likewise.
(vmlal_high_lane_u16): Likewise.
(vmlal_high_lane_u32): Likewise.
(vmlal_high_laneq_s16): Likewise.
(vmlal_high_laneq_s32): Likewise.
(vmlal_high_laneq_u16): Likewise.
(vmlal_high_laneq_u32): Likewise.
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def
index 336f9f9a56b07668678e5b384a89f518433da58b..152c2e6d361bdab0275e3b38759723fd2a3ffee5 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -300,6 +300,11 @@
BUILTIN_VD_HSI (QUADOPU_LANE, vec_umlsl_lane_, 0, NONE)
BUILTIN_VD_HSI (QUADOPU_LANE, vec_umlsl_laneq_, 0, NONE)
+ BUILTIN_VQ_HSI (QUADOP_LANE, smlal_hi_lane, 0, NONE)
+ BUILTIN_VQ_HSI (QUADOP_LANE, smlal_hi_laneq, 0, NONE)
+ BUILTIN_VQ_HSI (QUADOPU_LANE, umlal_hi_lane, 0, NONE)
+ BUILTIN_VQ_HSI (QUADOPU_LANE, umlal_hi_laneq, 0, NONE)
+
BUILTIN_VSD_HSI (BINOP, sqdmull, 0, NONE)
BUILTIN_VSD_HSI (TERNOP_LANE, sqdmull_lane, 0, NONE)
BUILTIN_VSD_HSI (TERNOP_LANE, sqdmull_laneq, 0, NONE)
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 1e9b4d933f3f9385d857b497e573de6aee25c57f..e741b656cb081e26b9e6e262ae50fab3716e1ed4 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -2180,6 +2180,76 @@
[(set_attr "type" "neon_mla__scalar_long")]
)
+(define_insn "aarch64_mlal_hi_lane_insn"
+ [(set (match_operand: 0 "register_operand" "=w")
+ (plus:
+ (mult:
+ (ANY_EXTEND: (vec_select:
+ (match_operand:VQ_HSI 2 "register_operand" "w")
+ (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
+ (ANY_EXTEND: (vec_duplicate:
+ (vec_select:
+ (match_operand: 4 "register_operand" "")
+ (parallel [(match_operand:SI 5 "immediate_operand" "i")])
+ (match_operand: 1 "register_operand" "0")))]
+ "TARGET_SIMD"
+ {
+operands[5] = aarch64_endian_lane_rtx (mode, INTVAL (operands[5]));
+return "mlal2\\t%0., %2., %4.[%5]";
+ }
+ [(set_attr "type" "neon_mla__scalar_long")]
+)
+
+(define_expand "aarch64_mlal_hi_lane"
+ [(match_operand: 0 "register_operand")
+ (match_operand: 1 "register_operand")
+ (ANY_EXTEND:(match_operand:VQ_HSI 2 "register_operand"))
+ (match_operand: 3 "register_operand")
+ (match_operand:SI 4 "immediate_operand")]
+ "TARGET_SIMD"
+{
+ rtx p = aarch64_simd_vect_par_cnst_half (mode, , true);
+ emit_insn (gen_aarch64_mlal_hi_lane_insn (operands[0],
+ operands[1], operands[2], p, operands[3], operands[4]));
+ DONE;
+}
+)
+
+(define_insn "aarch64_mlal_hi_laneq_insn"
+ [(set (match_operand: 0 "register_operand" "=w")
+ (plus:
+ (mult:
+ (ANY_EXTEND: (vec_select:
+ (match_operand:VQ_HSI 2 "register_operand" "w")
+ (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
+ (ANY_EXTEND: (vec_duplicate:
+ (vec_select:
+ (match_operand: 4 "register_operand" "")
+ (parallel [(match_operand:SI 5 "immediate_operand" "i")])
+ (match_operand: 1 "register_operand" "0")))]
+ "TARGET_SIMD"
+ {
+operands[5] = aarch64_endian_lane_rtx (mode, INTVAL (operands[5]));
+return "mlal2\\t%0., %2., %4.[%5]";
+ }
+ [(set_attr "type" "neon_mla__scalar_long")]
+)
+
+(define_expand "aarch64_mlal_hi_laneq"
+ [(match_operand: 0 "register_operand")
+ (match_operand: 1 "register_operand")
+ (ANY_EXTEND:(match_operand:VQ_HSI 2 "register_operand"))
+ (match_operand: 3 "register_operand")
+ (match_operand:SI 4 "immediate_operand")]
+ "TARGET_SIMD"
+{
+ rtx p = aarch64_simd_vect_par_cnst_half (mode, , true);
+ emit_insn (gen_aarch64_mlal_hi_laneq_insn (operands[0],
+ operands[1], operands[2], p, operands[3], operands[4]));
+ DONE;
+}
+)
+
(define_insn "aarch64_vec_mlsl_lane"
[(set (match_operand: 0 "register_operand" "=w")
(minus:
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index 7e2c2fc3827e773b960abc137b2cadea61a54577..ee68240f0d019a4a3be89e1e923cb14ee8026468 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -7182,117 +7182,69 @@ vmla_u32 (uint32x2_t __a, uint32x2_t __b,