[PATCH libX11 1/2] xcb_io: Fix Xlib 32-bit request number wrapping

Mouse mouse at Rodents-Montreal.ORG
Sun Nov 17 15:33:41 PST 2013


>>>     *wide = new + ((unsigned long) (new < *wide) << 16 << 16);
>>> The comment says "Treating the comparison as a 1 and shifting it
>>> avoids a conditional branch".
>> Only on architectures with conditional moves - and, on those, the
>> version using ? : is likely to compile down to a conditional move
>> anyway.  I think that comment should be fixed.
> What do you mean exactly?

Computing the numeric value of (a < b) - as opposed to using it in a
control-flow construct - is normally implemented much the same way that
((a < b) ? 1 : 0) is.  By definition of the < operator, they are
semantically identical anyway.

> I thought the comment was saying that using "(x < y) << z" is
> avoiding a conditinal branch introduced by using an "if" or "? :" in
> some way to get the calculation done.

That's what I think the comment is saying, yes.  I also think it's
false - or, at least, it's false more often than it's true, and in a
way that's unpredictable from the point of view of anyone who actually
needs the comment.

On architectures without conditional moves, it's difficult[%] to
compute the numerical value of (x < y) without a conditional branch.
And on architectures with conditional moves, ((x < y) ? 1 : 0) will
likely use a conditional move rather than a branch anyway.

> Isn't the comment true then?

It depends on the compiler, the target CPU architecture, and possibly
other things (like the optimization tradeoffs the compiler has been
told to use).  But if the optimizer is even half-decent, (x < y) << z
and ((x < y) ? 1 : 0) << z will compile to exactly the same
instructions.

I think it is likely enough that it's false that leaving the comment
there with that wording is a bad idea; I also see it as a instance of
pushing a very very machine-dependent tradeoff up to the C level,
something that is better left to the optimizer, or at the very least
buried in a machine-dependent preprocessor macro.

[%] Not impossible; it can be done with arithemtic and logical
    operations.  I'd render the core of the idea in 32-bit C as
    ((x-y)>>31)&1 - that's got issues with numbers large enough that
    their high few bits aren't all the same, but they can be fixed with
    a little more code.

/~\ The ASCII				  Mouse
\ / Ribbon Campaign
 X  Against HTML		mouse at rodents-montreal.org
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


More information about the xorg-devel mailing list