This is an archive of the discontinued LLVM Phabricator instance.

[X86] Fix i128 argument passing under SysV ABI
ClosedPublic

Authored by nikic on Aug 17 2023, 3:41 AM.

Details

Summary

The x86_64 SysV ABI specifies that __int128 is passed either in two registers (if available) or in a 16 byte aligned stack slot. GCC implements this behavior. However, if only one free register is available, LLVM will instead pass one half of the i128 in a register, and the other on the stack.

Make sure that either both are passed in registers or both on the stack.

Fixes https://github.com/llvm/llvm-project/issues/41784. The patch is basically what @craig.topper proposed to do there.

Diff Detail

Event Timeline

nikic created this revision.Aug 17 2023, 3:41 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 17 2023, 3:41 AM
nikic requested review of this revision.Aug 17 2023, 3:41 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 17 2023, 3:41 AM
pengfei accepted this revision.Aug 17 2023, 7:12 PM

Change looks good to me. Maybe add the ABI fix in clang ReleaseNotes?

This revision is now accepted and ready to land.Aug 17 2023, 7:12 PM

Do we have a way to detect it's from i128 and only do for it? I think we will increase unnecessary load/stores to normal 64-bit argument passing which would be more common in practice.

Do we have a way to detect it's from i128 and only do for it? I think we will increase unnecessary load/stores to normal 64-bit argument passing which would be more common in practice.

I think the CCIfSplit means it was larger than i64 to start.

See also https://reviews.llvm.org/D86310 which is needed in addition to this to fix i128 ABI for non-Clang LLVM frontends (I think that patch is also ready for a review at this point)

Do we have a way to detect it's from i128 and only do for it? I think we will increase unnecessary load/stores to normal 64-bit argument passing which would be more common in practice.

I think the CCIfSplit means it was larger than i64 to start.

That's great! Thanks Craig!

This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptAug 21 2023, 2:44 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
RalfJung added a subscriber: RalfJung.EditedSep 13 2023, 2:33 AM

I think the CCIfSplit means it was larger than i64 to start.

What about the case where R9 would take the *second* half of a split i128 (i.e., the value gets split across R8 and R9)? Does that still work after this patch?

I think the CCIfSplit means it was larger than i64 to start.

What about the case where R9 would take the *second* half of a split i128 (i.e., the value gets split across R8 and R9)? Does that still work after this patch?

Yes, this is the case tested in @in_reg. CCIfSplit only matches the first part of a split value, not all parts of it.