[LLVMdev] Arithmetic right shift emulation folding
me22
me22.ca at gmail.com
Wed Nov 18 07:55:59 PST 2009
Since C doesn't specify whether >> is arithmetic or logical on signed
numbers, portable code would have to emulate it. Is there a way that
LLVM will fold down to ashr in the IR?
I first tried this:
int ashr(unsigned a, unsigned b) {
return (signed)a < 0 ? ~((~a) >> b) : a >> b;
}
But that generates 4 BBs. Slightly better is this one:
int qaz(unsigned a, unsigned b) {
unsigned c = (signed)a < 0 ? ~0u : 0u;
return ((a^c) >> b)^c;
}
Which gives this branch-less IR:
define i32 @qaz(i32 %a, i32 %b) nounwind readnone {
entry:
%ones = ashr i32 %a, 31 ; <i32> [#uses=2]
%0 = xor i32 %ones, %a ; <i32> [#uses=1]
%1 = lshr i32 %0, %b ; <i32> [#uses=1]
%2 = xor i32 %1, %ones ; <i32> [#uses=1]
ret i32 %2
}
Is there any way to do better?
Thanks,
~ Scott
More information about the llvm-dev
mailing list