This is an archive of the discontinued LLVM Phabricator instance.

[LegalizeTypes] Add a simple expansion for SMULO when a libcall isn't available.
ClosedPublic

Authored by craig.topper on Aug 5 2021, 9:45 AM.

Details

Summary

This isn't optimal, but prevents crashing when the libcall isn't
available. It just calculates the full product and makes sure the high bits
match the sign of the low half. Each of the pieces should go through their own
type legalization.

This can make D107420 unnecessary.

Needs tests, but I wanted to start discussion about D107420.

Diff Detail

Event Timeline

craig.topper created this revision.Aug 5 2021, 9:45 AM
craig.topper requested review of this revision.Aug 5 2021, 9:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 5 2021, 9:45 AM

Add tests. Disable i128 libcall for 32-bit x86.

pengfei added inline comments.Aug 5 2021, 7:08 PM
llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
4063

Seems Lo and Hi are not used?

craig.topper added inline comments.Aug 5 2021, 7:10 PM
llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
4063

They are output references passed to this function see line 3969.

pengfei added inline comments.Aug 5 2021, 7:10 PM
llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
4063

Oh, I saw them in the function arguments. Sorry for the noise.

I haven't taken a look into gcc's generated code. Do you think gcc implements i256 signed mul overflow check in this same way? Hope you know...

FreddyYe accepted this revision.Aug 5 2021, 8:18 PM

LGTM.

This revision is now accepted and ready to land.Aug 5 2021, 8:18 PM

I haven't taken a look into gcc's generated code. Do you think gcc implements i256 signed mul overflow check in this same way? Hope you know...

I'm not sure if gcc can generate an i256 overflow check. But I can tell you the i128 code this patch generates does not match gcc. gcc checks whether the upper half of the inputs matches the sign of the lower half and dispatches to 4 different cases. There are two cases where one input is large and one is small that share the same code by commuting the inputs. SelectionDAG can't create branches so it's difficult to do exactly the same thing.