How to force GCC to assume that a floating-point expression is non-negative?

You can write assert(x*x >= 0.f) as a compile-time promise instead of a runtime check as follows in GNU C: #include <cmath> float test1 (float x) { float tmp = x*x; if (!(tmp >= 0.0f)) __builtin_unreachable(); return std::sqrt(tmp); } (related: What optimizations does __builtin_unreachable facilitate? You could also wrap if(!x)__builtin_unreachable() in a macro and call … Read more

Assembly bubble sort swap

I think I’d use pointers into the current position into the list, instead of an index that needs to be scaled every time you use it: mov esi, offset list top: mov edi, esi inner: mov eax, [edi] mov edx, [edi+4] cmp eax, edx jle no_swap mov [edi+4], eax mov [edi], edx no_swap: add edi, … Read more

Why is the “start small” algorithm for branch displacement not optimal?

Here’s a proof that, in the absence of the anomalous jumps mentioned by harold in the comments, the “start small” algorithm is optimal: First, let’s establish that “start small” always produces a feasible solution — that is, one that doesn’t contain any short encoding of a too-long jump. The algorithm essentially amounts to repeatedly asking … Read more

Shadow space example

The shadow space must be provided directly previous to the call. Imagine the shadow space as a relic from the old stdcall/cdecl convention: For WriteFile you needed five pushes. The shadow space stands for the last four pushes (the first four arguments). Now you need four registers, the shadow space (just the space, contents don’t … Read more