Expand MULO with constant power of two operand to a shift. The overflow is checked with (x << shift) >> shift == x.
Details
Details
Diff Detail
Diff Detail
- Repository
- rL LLVM
Event Timeline
llvm/test/CodeGen/X86/mulo-pow2.ll | ||
---|---|---|
30 ↗ | (On Diff #189560) | This being optimized is a nice side-effect, but we really should have a fold for mulo(x, 1). |
109 ↗ | (On Diff #189560) | This code is generated by the mulo(x, 2) -> addo(x, x) fold and seems worse than what we'd get from the shift expansion. Not sure what to do about it. |
llvm/test/CodeGen/X86/mulo-pow2.ll | ||
---|---|---|
133 ↗ | (On Diff #189560) | This one isn't right ... INT_MIN can be multiplied by 0 and 1, not by 0 and -1. |
llvm/test/CodeGen/ARM/umulo-32.ll | ||
---|---|---|
41 ↗ | (On Diff #189987) | We're doing a select of setcc here, both get expanded and the setcc is converted into this construction. |
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | ||
---|---|---|
5529 ↗ | (On Diff #189987) | (!isSigned || C.isNonNegative()) is specifically supposed to handle llvm.smul.with.overflow.i32(%x, INT_MIN)? Can't you just convert that to llvm.umul.with.overflow.i32(%x, INT_MIN) and lower it using an unsigned shift? |
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | ||
---|---|---|
5529 ↗ | (On Diff #189987) | Yes, you're right. I've implemented this now. |