Currently our AVRShiftExpand pass expands only 32-bit shifts, with the
assumption that other kinds of shifts (e.g. 64-bit ones) are
automatically reduced to 8-bit ones by LLVM during ISel.
However this is not always true and causes problems in the rust-lang runtime.
This commit changes the logic a bit, so that instead of expanding only
32-bit shifts, we expand shifts of all types except 8-bit and 16-bit.
This is not the most optimal solution, because 64-bit shifts can be
expanded to 32-bit shifts which has been deeply optimized.
I've checked the generated code using rustc + simavr, and all shifts
seem to behave correctly.
Spotted in the wild in rustc:
https://github.com/rust-lang/compiler-builtins/issues/523https://github.com/rust-lang/rust/issues/112140
Reviewed By: benshi001
Differential Revision: https://reviews.llvm.org/D154785
This patch makes sure shift instructions such as this one:
%result = shl i32 %n, %amount
are expanded just before the IR to SelectionDAG conversion to a loop so
that calls to non-existing library functions such as __ashlsi3 are
avoided. The generated code is currently pretty bad but there's a lot of
room for improvement: the shift itself can be done in just four
instructions.
Differential Revision: https://reviews.llvm.org/D96677