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 davide on Nov 11 2015, 2:39 PM. Authored by
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 retq sizeInBits(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 retq Which 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.