[Interest] How does one use Q_ASSUME?

Giuseppe D'Angelo giuseppe.dangelo at kdab.com
Sun May 26 14:21:36 CEST 2019


Il 26/05/19 12:36, René J. V. Bertin ha scritto:
> Giuseppe D'Angelo via Interest wrote:
> 
> Hi,
> 
>> On the other hand, Q_ASSUME(cond) tells the compiler that cond is true,
> 
> After reading the MS doc I sort of understand how you can use the construct to
> implement a Q_UNREACHABLE (but in the example given I don't see the codegen
> advantage of `default: Q_UNREACHABLE` vs. not adding a `default:` at all).

There isn't usually a codegen advantage between the two (or maybe there 
is only in some corner cases; to my book that's a bug report for "missed 
optimization"). For instance: on compilers lacking a dedicated builtin, 
Q_ASSUME(x) is indeed implemented as

> if (x) {} else { __builtin_unreachable(); }

which clearly shows the semantics of Q_ASSUME, and that it can be 
implemented in terms of Q_UNREACHABLE.




>> Look here at a possible example at how it can improve codegen:
>>
>> https://gcc.godbolt.org/z/KlWBRY
> 
> Not really, I'm afraid.
> 
> The only thing that's evident to me from there is that there is much fewer
> generated machine code when you add the assume statement. I don't see at all why
> that would be, what difference it would make for the loop that it is always
> iterated over a multiple of 16. I thought the difference might be in evaluating
> the `i < count` expression, but even after trying to factor that out the
> difference remains:
> https://gcc.godbolt.org/z/2Zclp5

In my example, if we tell the compiler that count is a multiple of 16, 
then the compiler can do a better job at generating code. In the 
specifics, the compiler can use a vectorized loop using AVX to to the 
sum 8 integers at a time. If the compiler knows that count is a multiple 
of 16, then that loop is enough, and indeed only that loop gets emitted. 
If the compiler does NOT know, then it does the vectorized loop as much 
as it can, but then it has to deal with the remaining 0-7 integers, 
which get dealt in the following generated code, which is an unrolled 
for loop.

In your example, the compiler can easily deduce that i and count are 
_both_ multiple of 16 (because they have the same value), so it applies 
the same optimization. Maybe the codegen is slightly different due to 
the decreasing loop induction variable that could throw the optimizer off.


> Take home message for me is that this is a construct that's probably useful only
> if you have very intimate knowledge about code generation, and thus not very
> cross-platform/compiler (and even less cross-architecture). Except for the
> Q_UNREACHABLE thing.

The optimization is probably the most compelling aspect of it, because 
Q_ASSUMEs are left in release builds. The other aspect is of course an 
indication for who reads the code -- that you're making an assumption on 
certain conditions, so the following code is valid IFF those conditions 
hold.

> 
> What I was hoping it might do is what the Qt documentation suggests, a more
> graceful version of a Q_ASSERT. That is, a version that does the usual abort in
> debug builds, but becomes a regular if in production code. I've seen too many
> examples of coding where a Q_ASSERT is used to guard against situations that are
> *assumed* never to occur, and then forgotten (or the devs assume everyone else
> uses debug/development builds). In many if not most of those cases it's trivial
> to add a graceful handling of the situation.

In production code Q_ASSUME is left (as a hint to the compiler); 
Q_ASSERT disappears. That's why they're different macros (although, as 
you point out, conceptually they indicate the same thing -- that a 
condition is always true, else UB).

In debug builds, Q_ASSUME becomes a Q_ASSERT, so you can debug the case 
in which the assumption is false.


Hope this helps,

-- 
Giuseppe D'Angelo | giuseppe.dangelo at kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4329 bytes
Desc: Firma crittografica S/MIME
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20190526/cbad8784/attachment.bin>


More information about the Interest mailing list