[Mesa-dev] [PATCH 4/5] nir: Recognize mul(b2f(a), b2f(b)) as a logical AND.

Connor Abbott cwabbott0 at gmail.com
Wed Mar 18 22:22:53 PDT 2015


On Thu, Mar 19, 2015 at 12:35 AM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> On Wed, Mar 18, 2015 at 9:31 PM, Matt Turner <mattst88 at gmail.com> wrote:
>> On Wed, Mar 18, 2015 at 9:27 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
>>> On Wed, Mar 18, 2015 at 8:59 PM, Connor Abbott <cwabbott0 at gmail.com> wrote:
>>>> On Wed, Mar 18, 2015 at 11:35 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
>>>>>
>>>>> On Mar 18, 2015 8:32 PM, "Matt Turner" <mattst88 at gmail.com> wrote:
>>>>>>
>>>>>> On Wed, Mar 18, 2015 at 7:39 PM, Jason Ekstrand <jason at jlekstrand.net>
>>>>>> wrote:
>>>>>> > On Wed, Mar 18, 2015 at 11:37 AM, Matt Turner <mattst88 at gmail.com>
>>>>>> > wrote:
>>>>>> >> Transform this into b2f(and(a, b)).
>>>>>> >>
>>>>>> >> total instructions in shared programs: 6205448 -> 6204391 (-0.02%)
>>>>>> >> instructions in affected programs:     284030 -> 282973 (-0.37%)
>>>>>> >> helped:                                903
>>>>>> >> HURT:                                  6
>>>>>> >> ---
>>>>>> >>  src/glsl/nir/nir_opt_algebraic.py | 2 ++
>>>>>> >>  1 file changed, 2 insertions(+)
>>>>>> >>
>>>>>> >> diff --git a/src/glsl/nir/nir_opt_algebraic.py
>>>>>> >> b/src/glsl/nir/nir_opt_algebraic.py
>>>>>> >> index ef855aa..f956edf 100644
>>>>>> >> --- a/src/glsl/nir/nir_opt_algebraic.py
>>>>>> >> +++ b/src/glsl/nir/nir_opt_algebraic.py
>>>>>> >> @@ -95,6 +95,8 @@ optimizations = [
>>>>>> >>     (('fsat', a), ('fmin', ('fmax', a, 0.0), 1.0),
>>>>>> >> 'options->lower_fsat'),
>>>>>> >>     (('fsat', ('fsat', a)), ('fsat', a)),
>>>>>> >>     (('fmin', ('fmax', ('fmin', ('fmax', a, 0.0), 1.0), 0.0), 1.0),
>>>>>> >> ('fmin', ('fmax', a, 0.0), 1.0)),
>>>>>> >> +   # Emulating booleans
>>>>>> >> +   (('fmul', ('b2f', a), ('b2f', b)), ('b2f', ('iand', a, b))),
>>>>>> >
>>>>>> > Those are only equivalent if the sources are known booleans.
>>>>>> > Otherwise, no dice.
>>>>>>
>>>>>> Well... they're the source of a b2f. Are you saying that's not sufficient?
>>>>>
>>>>> No, that's not.  Fortunately, @bool should solve it for you in all of the
>>>>> cases you care about.
>>>>
>>>> I think Matt has a point here. There's not much point in defining how
>>>> b2f should work for things that aren't bools, and I'm fine with
>>>> transforms that produce "bad"/undefined results when the input isn't 0
>>>> or ~0. We should never get into that situation anyways. This is
>>>> different from the issue that compare instructions always have to
>>>> produce 0 or ~0, although both do stem from the fact that NIR doesn't
>>>> have a bool type.
>>>
>>> Ok... In that case, we need to define some things better.  For
>>> instance, bcsel is currently defined as "if nonzero do this else that"
>>> which is very different from "if ~0 do this else if 0 do that else...
>>
>> The only place I see any comments about bcsel is in nir_opcodes.py, which says:
>>
>> # Conditional Select
>> #
>> # A vector conditional select instruction (like ?:, but operating per-
>> # component on vectors). There are two versions, one for floating point
>> # bools (0.0 vs 1.0) and one for integer bools (0 vs ~0).
>>
>> I'd be great if we documented the opcodes much in the same way TGSI's
>> opcodes are documented. I get the sense that the documentation you're
>> referring to is only in your brain. :)
>
> Yes, official documentation would be good.  However, what I said above
> is what constant folding does as well as the i965 backend (we do a
> mov.nz to get the source).  Also, I thought there were other places
> where we explicitly say 0 vs. non-zero.

Hmm, I think I explicitly avoided trying to say "0 vs. non-zero"
because I wasn't sure if we wanted to do optimizations like this one.
I think I also wasn't sure what the semantics should be, but now it
seems clear that leaving it undefined is the best thing to do. As for
documentation, I think it should be enough to say something like "for
sources with a bool ALU type, the output value of the instruction is
undefined if the input is not 0 or ~0" in nir_opcodes.py. We should
never ever produce NIR where b2f (or anything else with a bool src)
gets anything other than 0 or ~0 as an input, so it's not even like
there's any user-visible change if we make it undefined. If you want
to translate something into NIR where your (hypothetical) source
language semantics is "if non-zero, then return x, otherwise return
y," then you can just use a compare to get the boolean value which
better communicates your expectation that there will be other random
junk handed to it and not just good ol' 0 and ~0, and should optimize
into the same thing (for i965) anyways.

>
> In any case, we need to define these things better and I'm 100% ok
> defining them as 0 vs ~0 and if you pass anything else, it's
> undefined.  That would sure make optimizations easier.
>
>>> who knows?"  I'm ok with either but we need to be clear.  If we stop
>>> using the sloppy version that may mean that when translating from
>>> other source languages that may not be strongly typed we'll have to do
>>> a ine with zero to fix it up.
>>> --Jason


More information about the mesa-dev mailing list