3 ms·
Yeah that div check works I guess, but as you say is horribly expensive. For the latter it looks like at least on recent versions of gcc, you can do something
by stormbrew 12y ago
Yeah that div check works I guess, but as you say is horribly expensive.
For the latter it looks like at least on recent versions of gcc, you can do something like (WARNING: Just a vague proof of concept, please don't use it. It might kill kittens):
uint64_t func(uint64_t a, uint64_t b)
{
unsigned __int128 res = (unsigned __int128)a * (unsigned __int128)b;
if (res >> 64) {
asm volatile ("nop;" ::); /* handle here */
}
return (uint64_t)res;
}
Which compiles to this in gcc -Os and -O3:
0: 48 89 f8 mov %rdi,%rax
3: 48 f7 e6 mul %rsi
6: 48 85 d2 test %rdx,%rdx
9: 74 01 je c <func+0xc>
b: 90 nop
c: f3 c3 repz retq
Which I'm pretty sure could be optimized further by using the overflow flag, but the compiler doesn't seem to want to ignore the upper word.
edit: and it probably suffers the same problem as described here: https://news.ycombinator.com/item?id=7848771 https://news.ycombinator.com/item?id=7848771 -- and also probably has general issues with signedness that would need to be further checked.
edit2: changed it to uints to simplify and avoid a whole class of problem. I still don't think you should go use this, though.
(inspiration from SO: http://stackoverflow.com/a/13187798 http://stackoverflow.com/a/13187798)
- danbruc 12y agoLooking at the GCC source [1] starting at line 150 this is almost what GCC actually does - perform the multiplication with twice the operand size and then check by shifting right but GCC compares the result of two shift operations differing by one in the shift amount. [1] https://github.com/mirrors/gcc/blob/master/libgcc/libgcc2.c https://github.com/mirrors/gcc/blob/master/libgcc/libgcc2.c
- stormbrew 12y agoFor future reference, you can link to a specific line in github with #LNNN. Which you can get by clicking on the line number. Pretty handy. https://github.com/mirrors/gcc/blob/master/libgcc/libgcc2.c#L151 https://github.com/mirrors/gcc/blob/master/libgcc/libgcc2.c#...