Open ancapdev opened 7 years ago
Could probably be fixed by putting !range metadata on boolean loads.
Would using i1
in our LLVM for Bool
be a feasible approach?
In theory that should probably work, yes. In practice you'll probably run into LLVM bugs if you try to do, because no other frontend does it.
IIRC that's probably why we didn't do it in the first place.
I thought we did for a while, and changed because of said LLVM bugs
The claim that no other frontend does it is no longer true! :)
Clang appears to use i1
:
https://blog.matthieud.me/2020/exploring-clang-llvm-optimization-on-programming-horror/
Some of us were looking at that blog post it on Slack and wondering why Julia couldn't make the same optimizations. Julia currently generates code for the naive loop, and then vectorizes it during optimization.
function isEven2(num::T) where T
numComp = zero(T)
even = true
while num != numComp
even = !even
numComp = numComp + one(T)
end
return even
end
I took the unoptimized code (@code_llvm optimize=false dump_module=true isEven2(Int32(300))
) and popped it into Godbolt, compiling with clang -O1
. This generates the naive loop in asm. But I noticed that one of the passes in the blog said "even is no longer a byte (i8) but stored directly as a single bit (i1), thus removing several conversion instructions." I tried manually removing the conversions and that resulted in the O(1) version being generated by clang!
Here's the version before and after my rewriting: https://gist.github.com/iamed2/863a8f329b006bdc200a1128dbf5bd6e
All this to say it seems like it might be a good idea to take another look at using i1
s for Bool
s.
Observing what looks like suboptimal codegen when loading and assigning
Bool
variables. It seems to undergo some transformation where I'm guessing it loses the information that it's aBool
type and upon assignment forces its value to[0, 1]
by binary and, which at least naively to me seems redundant.Example below, tested on
0.5.1
and0.6.0-pre.alpha
.LLVM output
Native x64 output