This enables constant folding for fls() [FreeBSD specific]. This should be quite straighforward (unless I got the math wrong, which I don't exclude).
Thanks!
Differential D14590
[SimplifyLibCalls] Constant folding for fls, flsl, flsll Authored by davide on Nov 11 2015, 2:39 PM.
Details This enables constant folding for fls() [FreeBSD specific]. This should be quite straighforward (unless I got the math wrong, which I don't exclude). Thanks!
Diff Detail Event TimelineComment Actions SimplifyLibCalls needs to know how to translate the pair (DataLayout, C99 type) -> LLVM IR Type in order to make this transformation. Until then, there's no reliable way to know how big a long is and that could cause a wrong constant folding of fls(). I haven't audited all the transformations here, but I wouldn't be surprised if other functions are incorrectly transformed assuming sizes of primitive types. Comment Actions I'm not sure I follow the issue with long. If we see call i32 @flsl(i32 42) in the IR, "long" must be 32 bits; if we see call i32 @flsl(i64 42) in the IR, "long" must be 64 bits. Comment Actions https://llvm.org/bugs/show_bug.cgi?id=31385 You're absolutely right, there's no such problem as we actually have the type. I was under the impression we needed the correspondence with the C type but I was clearly wrong. Well, thanks for catching. Comment Actions
Comment Actions With llvm.ctlz(x, true) we end up producing slightly smaller code (at least on x86_64 FreeBSD) i.e. x != 0 ? (sizeInBits(x) - llvm.ctlz(x, true)) : 0 bsrq %rdi, %rcx xorl $-64, %ecx addl $65, %ecx xorl %eax, %eax testq %rdi, %rdi cmovnel %ecx, %eax retq x != 0 ? (sizeInBits(x) - llvm.ctlz(x, false)) : 0 # BB#0:
testq %rdi, %rdi
je .LBB0_1
# BB#2: # %cond.false
bsrq %rdi, %rax
xorq $63, %rax
jmp .LBB0_3
.LBB0_1:
movl $64, %eax
.LBB0_3: # %cond.end
movl $64, %ecx
subl %eax, %ecx
xorl %eax, %eax
testq %rdi, %rdi
cmovnel %ecx, %eax
retqsizeInBits(x) - llvm.ctlz(x, false) # BB#0:
testq %rdi, %rdi
je .LBB0_1
# BB#2: # %cond.false
bsrq %rdi, %rcx
xorq $63, %rcx
jmp .LBB0_3
.LBB0_1:
movl $64, %ecx
.LBB0_3: # %cond.end
movl $64, %eax
subl %ecx, %eax
retqWhich one do you prefer, 1) or 3) ?
Comment Actions That's weird... I would have guessed instcombine would kick in an canonicalize one way or the other. Anyway, the difference between 1 and 3 doesn't really matter. Comment Actions I'll go for 3, then. Comment Actions LGTM with typo fixed.
| ||||||||||||||||||||||||||||||||||||
Typo: fls, not ffs.