sse.md (reduc_plus_scal_v4df): Avoid the use of haddv4df...
authorRichard Biener <rguenther@suse.de>
Tue, 2 Oct 2018 13:06:54 +0000 (13:06 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 2 Oct 2018 13:06:54 +0000 (13:06 +0000)
2018-10-02  Richard Biener  <rguenther@suse.de>

* config/i386/sse.md (reduc_plus_scal_v4df): Avoid the use
of haddv4df, first reduce to SSE width and exploit the fact
that we only need element zero with the reduction result.
(reduc_plus_scal_v2df): Likewise.

From-SVN: r264785

gcc/ChangeLog
gcc/config/i386/sse.md

index c930bd2007c98940963f7a484d43f70a26c9d12f..65d5d7dd3313c79f71ce73327e99af96efc2517f 100644 (file)
@@ -1,3 +1,10 @@
+2018-10-02  Richard Biener  <rguenther@suse.de>
+
+       * config/i386/sse.md (reduc_plus_scal_v4df): Avoid the use
+       of haddv4df, first reduce to SSE width and exploit the fact
+       that we only need element zero with the reduction result.
+       (reduc_plus_scal_v2df): Likewise.
+
 2018-10-02  Eric Botcazou  <ebotcazou@adacore.com>
 
        * dojump.h (do_jump): Delete.
index 0b655726c115eeb470360f31d4c606c4823e470e..ce26994f61fa39cd6fa1decb5c7fb04415be4814 100644 (file)
    (match_operand:V4DF 1 "register_operand")]
   "TARGET_AVX"
 {
-  rtx tmp = gen_reg_rtx (V4DFmode);
-  rtx tmp2 = gen_reg_rtx (V4DFmode);
-  rtx vec_res = gen_reg_rtx (V4DFmode);
-  emit_insn (gen_avx_haddv4df3 (tmp, operands[1], operands[1]));
-  emit_insn (gen_avx_vperm2f128v4df3 (tmp2, tmp, tmp, GEN_INT (1)));
-  emit_insn (gen_addv4df3 (vec_res, tmp, tmp2));
-  emit_insn (gen_vec_extractv4dfdf (operands[0], vec_res, const0_rtx));
+  rtx tmp = gen_reg_rtx (V2DFmode);
+  emit_insn (gen_vec_extract_hi_v4df (tmp, operands[1]));
+  rtx tmp2 = gen_reg_rtx (V2DFmode);
+  emit_insn (gen_addv2df3 (tmp2, tmp, gen_lowpart (V2DFmode, operands[1])));
+  rtx tmp3 = gen_reg_rtx (V2DFmode);
+  emit_insn (gen_vec_interleave_highv2df (tmp3, tmp2, tmp2));
+  emit_insn (gen_adddf3 (operands[0],
+                        gen_lowpart (DFmode, tmp2),
+                        gen_lowpart (DFmode, tmp3)));
   DONE;
 })
 
 (define_expand "reduc_plus_scal_v2df"
   [(match_operand:DF 0 "register_operand")
    (match_operand:V2DF 1 "register_operand")]
-  "TARGET_SSE3"
+  "TARGET_SSE2"
 {
   rtx tmp = gen_reg_rtx (V2DFmode);
-  emit_insn (gen_sse3_haddv2df3 (tmp, operands[1], operands[1]));
-  emit_insn (gen_vec_extractv2dfdf (operands[0], tmp, const0_rtx));
+  emit_insn (gen_vec_interleave_highv2df (tmp, operands[1], operands[1]));
+  emit_insn (gen_adddf3 (operands[0],
+                        gen_lowpart (DFmode, tmp),
+                        gen_lowpart (DFmode, operands[1])));
   DONE;
 })