[Mesa-dev] nir/i965: Source modifiers on vecN opcodes

Thomas Helland thomashelland90 at gmail.com
Mon Nov 9 05:16:08 PST 2015


2015-11-09 12:55 GMT+01:00 Iago Toral <itoral at igalia.com>:
> Hi,
>
> Currently, NIR defines vecN operations as unsigned (integer). The fp64
> patches from Connor change this to float (I guess because we need to
> know the case where we are packing vectors of 64-bit floats). However,
> this makes it so that  nir_lower_source_to_mods turns this:
>
>         vec1 ssa_2 = fmov -ssa_1.y
>         vec3 ssa_3 = vec3 ssa_1, ssa_2, ssa_0
>
> into:
>
>         vec3 ssa_2 = vec3 ssa_1, -ssa_1.y, ssa_0
>
> This only happens because the vec3 operation is defined as a float
> operation now, otherwise it would not try to do this. It is not clear to
> me if this is by design, I mean, have this kind of things only kick-in
> for float/int and define vecN operations as unsigned to avoid this for
> them.
>
> The problem comes later when we call nir_lower_vec_to_movs in the i965
> vec4 backend. That pass generates a separate MOV for each component in
> the vector, but to do that properly when a negate is involved it needs
> to know if this is a float or an integer operand, which it  does not
> know at this point. The current code always emits an imov, which won't
> work if the operand is a float.
>
> I can think of two solutions for this:
>
> 1) Change nir_lower_source_to_mods so it does not try to rewrite alu
> operations where a source comes from a fmov with a negate, or at least
> if the instruction we are trying to rewrite is a vecN operation (or
> maybe allow this in scalar mode only?)
>
> 2) In nir_lower_vec_to_movs, if a source is negated, check its
> parent_instr and try to guess its type from that (in this example, we
> would see it came from fmov and we can say it is a float and emit fmov
> instead of imov). Not sure if this would work in all possible scenarios
> though.
>

FWIW method 2) was the method I chose when I needed to do something
similar for my range analysis pass. However, my intended solution (that
didn't get fully completed) was to implement such a thing in NIR, that
would check all operations we didn't know the type of, not just movs.

I did this the following way; check if all sources have the same type,
if they do then this gives us the type. If this fails then try to deduce the
type from the places where the result is used. This order was chosen
as it is safest to traverse upwards when deducing information.
This would then be incorporated in a nir_get_type_for_alu function.

It went something like this.

nir_get_type_for_alu()
{
   switch(alu-op)
   case "op_we're_sure_of":
      return type;

    type = get_type_from_sources();

    if (type != nir_type_none )
      return type;

    type = get_type_from_uses();

    if (type != nir_type_none )
      return type;

    panic();
}

get_type_from_source() and get_type_from_dest()
would then call nir_get_type_for_alu() recursively.

This might not be very pretty, but thought I'd share my take on it.

Regards,
Thomas


More information about the mesa-dev mailing list