How do the two shifts reduce to x? The top bit is zeroed as a result of those shifts.
Well ok but (x*3)/3 will be a lot worse :)
Re:Catching integer overflows in C
by Franciscouzo on Wednesday August 22, 2018 @01:30AM
(#17816525)
Not by a lot, the divide by constant can be optimized to a multiplication, if you're doing it in a loop (why would you care if you do it only once), you can reach a throughput of one multiplication per cycle, so (x*3)/3 would take 2 cycles on average.
This is a silly line of argument; optimizing (x*3)/3 to x unlocks further CSE, inlining, etc. so the benefit may be arbitrarily large.
Rust made the right tradeoff here but it is a tradeoff!
LLVM’s constant folding and canonicalization passes will convert (x * 2) / 2 from
%0 = mul i64 %x, i64 2
%1 = div i64 %0, i64 2
to
%0 = shl i64 %x, i64 1
%1 = shr i64 %0, i64 1
Which constant folding will reduce to just %x.