4 ms·
> Signed overflow/underflow remain UB (and it’s understandable that changing this behavior would have dramatic consequences) I think that the dramatic conseque
by pizlonator 3y ago
> Signed overflow/underflow remain UB (and it’s understandable that changing this behavior would have dramatic consequences)
I think that the dramatic consequences are only understandable if you succumb to mimetic contagion.
The consequences are real but not dramatic and possibly not even measurable in many workloads.
It just means that you’ll have an extra sign extension (one of the cheapest ops the CPU has) in a subset of your loops, namely the ones that had a 32 bit signed induction variable and the compiler could reason about that variable but only if it also could assume no wrapping. That’s a lot of caveats.
Most loops will be unaffected by making signed integer overflow defined. Anything that’s not in a loop will almost certainly be unaffected by this change. If you use size_t as your indices then you’ll definitely be unaffected.
So yeah. “Dramatic consequences”. I wish folks stopped exaggerating. There’s nothing dramatic here. It’s a fraction of a percent of perf maybe.
- rdtsc 3y ago> a 32 bit signed induction variable and the compiler could reason about that variable but only if it also could assume no wrapping. (Amateur C programmer silly question) I think I understand it as if we increment the variable (i+10) and use it in an if condition. With UB the compiler could skip that code altogether and assume it will never be reached?
- pizlonator 3y agoThe compiler has to assume that I+10 won’t overflow by virtue of I never being big enough. So, it’ll emit all of the code and UB won’t come into play. It’s more like this. If you say A[I] where I is 32 bit signed and you’re on a 64 bit target, then this lowers to: - sign extend I to get a 64-bit value - multiply it by the size of A’s element type - add that to A - then do the access The last three steps will be just one instruction in the common case on arm and x86. The first step will require a separate instruction on x86. The compiler can kill the sign extend if it’s sure that the integer value cannot be negative. That’s hard to prove. But you can almost prove it if you see code like: for (int i = 0; something; ++i) It looks like i starts out as zero and only grows! So it has to be positive! So if you say A[i] then no sign extend needed! But wait, what if ++i overflows? With signed int UB, the compiler can just assume it won’t overflow. And then it can prove that i is nonnegative. And then it can kill the sign extend on those CPUs where it’s not free, like x86. I’m a compiler writer. I know how valuable this optimization is. Namely, it’s the tiniest of benefits on some program/CPU combos. Modern languages like Java or Swift just give this well defined semantics and call it a day because this isn’t a good hill to die on. Fucking up the language isn’t worth 0.3% on some stupid benchmark, period.
- jzwinck 3y agoI agree with this, and I will take it a step further: people who want the compiler to know the ranges of their variables to enable better optimizations should use the various "assume" attributes/builtins which have existed for a long time. The compiler can do way more if it knows your loop count is max 5 than if it knows it is max 2 billion.
- rdtsc 3y agoThank you for detailed explanation. > Modern languages like Java or Swift just give this well defined semantics and call it a day because this isn’t a good hill to die on. Fucking up the language isn’t worth 0.3% on some stupid benchmark, period. I saw some projects just opt to use -fwrapv as a gcc option. clang I think has the same one too now. The docs for gcc mentions [1] "This flag enables some optimizations and disables others" [1] https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
- pizlonator 3y agoYeah. It would be great if either of these things happened: - signed overflow was defined to wrap like -fwrapv does. - overflow of any kind is guaranteed to trap. The latter would be better for sanity and security but I’ll take what I can get.
- deleted 3y ago[deleted]