On Thu, Apr 21, 2016 at 6:59 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Thu, Apr 21, 2016 at 3:54 PM, H.J. Lu <hjl.to...@gmail.com> wrote:
>> On Thu, Apr 21, 2016 at 6:48 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
>>> On Thu, Apr 21, 2016 at 3:43 PM, H.J. Lu <hjl.to...@gmail.com> wrote:
>>>> On Thu, Apr 21, 2016 at 6:33 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
>>>>> On Thu, Apr 21, 2016 at 2:59 PM, H.J. Lu <hjl.to...@gmail.com> wrote:
>>>>>
>>>>>>> We know, that const_int (-1) is allowed with TARGET_SSE2 and that
>>>>>>> const_wide_int (-1) is allowed with TARGET_AVX2. Probably we don't
>>>>>>> have to check AVX512F in standard_sse_constant_p, as it implies
>>>>>>> TARGET_AVX2.
>>>>>>>
>>>>>>> As said, it is the job of insn mode attributes to emit correct 
>>>>>>> instruction.
>>>>>>>
>>>>>>> Based on the above observations, mode checks for -1 are not needed in
>>>>>>> standard_sse_constant_p.
>>>>>>
>>>>>> void
>>>>>> ix86_expand_vector_move (machine_mode mode, rtx operands[])
>>>>>> {
>>>>>>   rtx op0 = operands[0], op1 = operands[1];
>>>>>>   /* Use GET_MODE_BITSIZE instead of GET_MODE_ALIGNMENT for IA MCU
>>>>>>      psABI since the biggest alignment is 4 byte for IA MCU psABI.  */
>>>>>>   unsigned int align = (TARGET_IAMCU
>>>>>>                         ? GET_MODE_BITSIZE (mode)
>>>>>>                         : GET_MODE_ALIGNMENT (mode));
>>>>>>
>>>>>>   if (push_operand (op0, VOIDmode))
>>>>>>     op0 = emit_move_resolve_push (mode, op0);
>>>>>>
>>>>>>   /* Force constants other than zero into memory.  We do not know how
>>>>>>      the instructions used to build constants modify the upper 64 bits
>>>>>>      of the register, once we have that information we may be able
>>>>>>      to handle some of them more efficiently.  */
>>>>>>   if (can_create_pseudo_p ()
>>>>>>       && register_operand (op0, mode)
>>>>>>       && (CONSTANT_P (op1)
>>>>>>           || (SUBREG_P (op1)
>>>>>>               && CONSTANT_P (SUBREG_REG (op1))))
>>>>>>       && !standard_sse_constant_p (op1))
>>>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>>>>
>>>>>> What should it return for  op1 == (VOIDmode) -1 when
>>>>>> TARGET_AVX is true and TARGET_AVX2 is false for
>>>>>> mode == TImode and mode == OImode?
>>>>>>
>>>>>>     op1 = validize_mem (force_const_mem (mode, op1));
>>>>>
>>>>> Let me rethink and redesign this whole mess, so we will have
>>>>> consistent predicates.
>>>>
>>>> The problem is because -1 has no mode.  We can't tell
>>>> if -1 is a valid SSE constant without mode.  That is my
>>>> change to standard_sse_constant_p and
>>>> ix86_expand_vector_move is for.   It is sufficient for
>>>> all my tests, including benchmark runs.
>>>
>>> I'm not against mode checks, but IMO, we have to do these checks in
>>> predicates, where we know operand mode.
>>
>> I tried and it doesn't work since the correct mode may not be always
>> available in predicates.  Yes, they pass mode.  But they just do
>>
>> mode = GET_MODE (op);
>>
>> which returns VOIDmode for -1.
>
> Well, looking at generated gcc/insns-preds.c, the predicates do:
>
> (mode == VOIDmode || GET_MODE (op) == mode).
>
> They *check* and don't *assign* "mode" variable.
>
> So, I see no problem checking "mode" variable (that gets the value
> from the pattern) in the predicates.

This is an incomplete list:

combine.c:   && ! push_operand (dest, GET_MODE (dest)))
expr.c:  if (push_operand (x, GET_MODE (x)))
expr.c:  && ! push_operand (x, GET_MODE (x))))
gcse.c:   && ! push_operand (dest, GET_MODE (dest)))
gcse.c:  if (general_operand (exp, GET_MODE (reg)))
ifcvt.c:  if (! general_operand (cmp_a, GET_MODE (cmp_a))
ifcvt.c:      || ! general_operand (cmp_b, GET_MODE (cmp_b)))
ifcvt.c:      else if (general_operand (b, GET_MODE (b)))
ifcvt.c:  if (! general_operand (a, GET_MODE (a)) || tmp_a)
ifcvt.c:  if (! general_operand (b, GET_MODE (b)) || tmp_b)
ira-costs.c:      if (address_operand (op, GET_MODE (op))
ira-costs.c:      && general_operand (SET_SRC (set), GET_MODE (SET_SRC (set))))
lower-subreg.c:      if (GET_MODE (op_operand) != word_mode
lower-subreg.c:      && GET_MODE_SIZE (GET_MODE (op_operand)) > UNITS_PER_WORD)
lower-subreg.c:                                         GET_MODE (op_operand),
lra-constraints.c: if (simplify_operand_subreg (i, GET_MODE (old)) ||
op_change_p)
optabs.c:  create_output_operand (&ops[0], target, GET_MODE (target));
optabs.c:  create_input_operand (&ops[1], op0, GET_MODE (op0));
postreload-gcse.c:      if (! push_operand (dest, GET_MODE (dest)))
postreload-gcse.c:  && general_operand (src, GET_MODE (src))
postreload-gcse.c:  && general_operand (dest, GET_MODE (dest))
postreload-gcse.c:  && general_operand (src, GET_MODE (src))

IRA and LRA use GET_MODE and pass it to predicates.

-- 
H.J.

Reply via email to