This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Vector permutation support for x86


@@ -1724,8 +1723,8 @@
 	  (match_operand:FMA4MODEF4 2 "nonimmediate_operand" ""))
 	 (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "")))]
   "TARGET_FMA4
-   && !ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)
-   && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)
+   && MEM_P (operands[2])
+   && (MEM_P (operands[1]) || MEM_P (operands[3]))
    && !reg_mentioned_p (operands[0], operands[1])
    && !reg_mentioned_p (operands[0], operands[2])
    && !reg_mentioned_p (operands[0], operands[3])"

This is the splitter under fma4_fmadd<mode>4256", but the same comment applies to all of the fma4 splitters.


First, MEM_P(operands[2]) would be better written as "memory_operand" in the match_operand for op2. Second, two of the reg_mentioned_p tests are *always* going to be false for these patterns, for the simple reason that operands[0] is a vector float register and the only registers that would be present in a memory operand is an address register.

So I think these splitters would be better written:

;; Split fmadd with two memory operands into a load and the fmadd.
(define_split
  [(set (match_operand:FMA4MODEF4 0 "register_operand" "")
        (plus:FMA4MODEF4
         (mult:FMA4MODEF4
          (match_operand:FMA4MODEF4 1 "register_operand" "")
          (match_operand:FMA4MODEF4 2 "memory_operand" ""))
         (match_operand:FMA4MODEF4 3 "memory_operand" "")))]
  "TARGET_FMA4"
  [(set (match_dup 0)
	(plus:FMA4MODEF4
	  (mult:FMA4MODEF4 (match_dup 1) (match_dup 2))
	  (match_dup 3)))]
{
  if (!ix86_expand_fma4_multiple_memory (operands, <MODE>mode))
    FAIL;
})

bool
ix86_expand_fma4_multiple_memory (rtx operands[],
				  enum machine_mode mode)
{
  rtx scratch = operands[0];

  gcc_assert (register_operand (operands[0], mode));
  gcc_assert (register_operand (operands[1], mode));
  gcc_assert (MEM_P (operands[2]) && MEM_P (operands[3]));

  if (reg_mentioned_p (scratch, operands[1]))
    {
      if (!can_create_pseudo_p ())
	return false;
      scratch = gen_reg_rtx (mode);
    }

  emit_move_insn (scratch, operands[3]);
  if (rtx_equal_p (operands[2], operands[3]))
    operands[2] = operands[3] = scratch;
  else
    operands[3] = scratch;
  return true;
}

@@ -2030,11 +2020,10 @@
 	(minus:SSEMODEF4
 	 (mult:SSEMODEF4
 	  (neg:SSEMODEF4
-	   (match_operand:SSEMODEF4 1 "nonimmediate_operand" "x,x"))
-	  (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm"))
+	   (match_operand:SSEMODEF4 1 "register_operand" "%x,x"))
+	  (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,m"))
 	 (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x")))]

Careful -- these with NEG are not commutative. Five instances.




r~


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]