ASSERT and __builtin_unreachable
Marc Glisse
marc.glisse at inria.fr
Tue Sep 3 06:35:49 UTC 2019
On Tue, 3 Sep 2019, Niels Möller wrote:
> I think we discussed this earlier, but I don't recall the conclusion, if
> any. Would it make sense to use ASSERT to guide the compiler, and define
> it like
>
> #define ASSERT(expr) do { if (!(expr)) __builtin_unreachable(); } while (0)
>
> (unless building with --enable-assert)?
>
> The idea is to tell the compiler to assume that the asserted expression
> is true, and not care what the behavior of the generated code is in case
> it nevertheless happens to be false at run time.
>
> As far as I understand, this should aid optimization in some (rare?)
> cases. Drawbacks are small: we'd need a configure test for
> __builtin_unreachable, and there are a few places with code like
>
> ASSERT_CODE (char *bp_orig = bp - bytes);
> ...
> ASSERT (bp > bp_orig);
>
> that needs the current definition of ASSERT and have to be updated in
> one way or the other.
That seems fine for small assertions, say ASSERT(x>0), but it seems bad
for more expensive ones, because it becomes an ASSERT_ALWAYS. In ASSERT
(refmpn_mul_1c (prod, rp, size, divisor, carry) == carry_orig) we may end
up calling refmpn_mul_1c needlessly, same in ASSERT (mpn_mod_1 (up, n, d)
== 0). So we may need to introduce ASSERT_EXPENSIVE at the same time.
There are other drawbacks, it may hinder inlining because the tests make
the functions temporarily bigger than they should be (though
__builtin_constant_p is much worse in that respect), and it may limit
other optimizations, but we can probably ignore that unless we notice a
regression.
--
Marc Glisse
More information about the gmp-devel
mailing list