Live data from Hacker News

Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

1f6042.blogspot.com

151–152 of 152 posts

Re: Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

#151
post #3

Both recent GCC and Clang are able to generate the most optimal version for std::clamp() if you add something like -march=znver1, even at -O1 [0]. Interesting! [0] https://godbolt.org/z/YsMMo7Kjz

But then it uses AVX instructions. (You can replace -march=znver1 with just -mavx.) When AVX isn’t enabled, the std::min + std::max example still uses fewer instructions. Looks like a random register allocation failure.

I don't think it's a register allocation failure but is in fact necessitated by the ABI requirement (calling convention) for the first parameter to be in xmm0 and the return value to also be placed into xmm0.

So when you have an algorithm like clamp which requires v to be "preserved" throughout the computation you can't overwrite xmm0 with the first instruction, basically you need to "save" and "restore" it which means an extra instruction.

I'm not sure why this causes the extra assembly to be generated in the "realistic" code example though. See https://godbolt.org/z/hd44KjMMn

Re: Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

#152

Earlier quoted context omitted.

I spent most of my career working with rsqrt haha. And had my fair share of non-754 architectures too! Every 754 architecture (including SSE) I've worked on has an accurate sqrt(). I'm assuming you're talking about with "fast math" enabled? In which case all bets are off anyway!

No; compilers have done this even without fast-math. Gcc does not seem to do this anymore, but still does plenty of unsafe optimizations by default, like FMA. Or maybe the library you use...

Argh, sounds really frustrating! It's hard enough to get accuracy when you can control operations never mind when the compiler is doing magic behind the scenes!

FMAs were difficult. The Visual Studio compiler in particular didn't support purposeful FMAs for SSE instructions so you had to rely on the compiler to recognise and replace multiply-additions. Generally I want FMAs because they're more accurate but I want to control where they go.

Post reply on HN