And we all know about the looping behavior, it isn't surprising.
The only surprising part would be if the compiler decides to use inc vs add, not that it really matters to the result.
And we all know about the looping behavior, it isn't surprising.
The only surprising part would be if the compiler decides to use inc vs add, not that it really matters to the result.
I'm not sure what you are talking about?
There's a difference between how your processor behaves when given some specific instructions, and what shenanigans your C compiler gets up to.
See eg https://godbolt.org/z/YY69Ezxnv and tell me where the ADD instruction shows up in the compiler output. Feel free to pick a different compiler target than Risc-V.
If you change the code so that the value of `a` is used, then the output is as expected: https://godbolt.org/z/78eYx37WG
Dead code elimination only works here because integer overflow is UB.
He wrote an example where the result of `a+1` isn't necessary, so the compiler doesn't emit an ADDI even though the literal text of the C source contains the substring "a += 1".
Your version has the same issue:
unsigned int square2(unsigned int num) {
unsigned int a = num;
a += 1;
if (num < a) return num * num;
return num;
}
The return value doesn't depend on `a+1`, so the compiler can optimize it to just a comparison.If you change it to this:
unsigned int square2(unsigned int num) {
unsigned int a = num;
a += 1;
if (num < a) return num * a;
return num;
}
then the result of `a+1` is required to compute the result in the first branch, and therefore the ADDI instruction is emitted.The (implied) disagreement is whether a language can be considered to be "portable assembly" if its compiler elides unnecessary operations from the output. I think that sort of optimization is allowed, but 'eru (presumably) thinks that it's diverging too far from the C source code.
if (num < a) return num * num;
/*else*/ return num;
A control dependency is still a dependencyIf the code returns `num * a` then the value of `a` is now necessary, and must be computed before the function returns.
For signed integer addition the compiler is allowed to assume that `(num < (num + 1))` is true, so the comparison can be removed entirely.
That's not directly what the compiler assumes. The direct problem is in 'a + 1' having undefined behaviour, and that transitively allows the assumption on the comparison that you mentioned.
This was an example where 'a + 1' doesn't compile to an add instruction.
https://godbolt.org/z/vv9rvKsxn
This isn’t qualitatively different from what the JVM JIT would do, but Java isn’t considered portable assembly.
I guess if you compile with optimizations completely off, you get something that is assembly-like, but I’ve never seen that in prod code.
No, the result of the 'a+1' is necessary in my version. And if you change the type from 'int' to 'unsigned' you will see that the compiler no longer just omits the addition.