diff mbox

[i386] Don't expand vector abs+neg to xor immediately

Message ID 4CC1E8C5.2060602@redhat.com
State New
Headers show

Commit Message

Richard Henderson Oct. 22, 2010, 7:40 p.m. UTC
This solves the problem that Richi saw on x86 with fma
plus negation on vectors not being merged into fnma etc
during combine.

Tested on x86_64-linux.


r~

Comments

H.J. Lu Oct. 23, 2010, 3:50 p.m. UTC | #1
On Fri, Oct 22, 2010 at 12:40 PM, Richard Henderson <rth@redhat.com> wrote:
> This solves the problem that Richi saw on x86 with fma
> plus negation on vectors not being merged into fnma etc
> during combine.
>
> Tested on x86_64-linux.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46144
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6e00d50..5f04fc4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@ 
+2010-10-22  Richard Henderson  <rth@redhat.com>
+
+	* config/i386/i386.c (ix86_expand_fp_absneg_operator): Produce
+	NEG+USE for vectors as well.
+	* config/i386/i386.md (*absneg<VEC_FLOAT_MODE>2): New pattern
+	and splitter.
+
 2010-10-22  Changpeng Fang  <changpeng.fang@amd.com>
 
 	* gcc/config/i386/bdver1.md: New file.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 547fe5f..ee88b06 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -15901,7 +15901,7 @@  void
 ix86_expand_fp_absneg_operator (enum rtx_code code, enum machine_mode mode,
 				rtx operands[])
 {
-  rtx mask, set, use, clob, dst, src;
+  rtx mask, set, dst, src;
   bool use_sse = false;
   bool vector_mode = VECTOR_MODE_P (mode);
   enum machine_mode vmode = mode;
@@ -15929,26 +15929,26 @@  ix86_expand_fp_absneg_operator (enum rtx_code code, enum machine_mode mode,
   dst = operands[0];
   src = operands[1];
 
-  if (vector_mode)
-    {
-      set = gen_rtx_fmt_ee (code == NEG ? XOR : AND, mode, src, mask);
-      set = gen_rtx_SET (VOIDmode, dst, set);
-      emit_insn (set);
-    }
-  else
+  set = gen_rtx_fmt_e (code, mode, src);
+  set = gen_rtx_SET (VOIDmode, dst, set);
+
+  if (mask)
     {
-      set = gen_rtx_fmt_e (code, mode, src);
-      set = gen_rtx_SET (VOIDmode, dst, set);
-      if (mask)
-        {
-          use = gen_rtx_USE (VOIDmode, mask);
+      rtx use, clob;
+      rtvec par;
+
+      use = gen_rtx_USE (VOIDmode, mask);
+      if (vector_mode)
+	par = gen_rtvec (2, set, use);
+      else
+	{
           clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
-          emit_insn (gen_rtx_PARALLEL (VOIDmode,
-				       gen_rtvec (3, set, use, clob)));
+	  par = gen_rtvec (3, set, use, clob);
         }
-      else
-	emit_insn (set);
+      emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
     }
+  else
+    emit_insn (set);
 }
 
 /* Expand a copysign operation.  Special case operand 0 being a constant.  */
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index b45d733..d80be88 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -585,6 +585,24 @@ 
   ""
   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
 
+(define_insn_and_split "*absneg<mode>2"
+  [(set (match_operand:VEC_FLOAT_MODE 0 "register_operand" "=x,x")
+	(match_operator:VEC_FLOAT_MODE 3 "absneg_operator"
+	  [(match_operand:VEC_FLOAT_MODE 1 "nonimmediate_operand" "0,xm")]))
+   (use (match_operand:VEC_FLOAT_MODE 2 "nonimmediate_operand" "xm,0"))]
+  "SSE_VEC_FLOAT_MODE_P (<MODE>mode) || AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+{
+  rtx set;
+  set = gen_rtx_fmt_ee (GET_CODE (operands[3]) == NEG ? XOR : AND,
+			<MODE>mode, operands[1], operands[2]);
+  set = gen_rtx_SET (VOIDmode, operands[0], set);
+  emit_insn (set);
+  DONE;
+})
+
 (define_expand "<plusminus_insn><mode>3"
   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
 	(plusminus:AVX256MODEF2P