This is an archive of the discontinued LLVM Phabricator instance.

[clang][RISCV] Fix incorrect ABI lowering for inherited structs under hard-float ABIs
ClosedPublic

Authored by asb on Aug 11 2022, 6:59 AM.

Details

Summary

The hard float ABIs have a rule that if a flattened struct contains either a single fp value, or an int+fp, or fp+fp then it may be passed in a pair of registers (if sufficient GPRs+FPRs are available). detectFPCCEligibleStruct and the helper it calls, detectFPCCEligibleStructHelper examine the type of the argument/return value to determine if it complies with the requirements for this ABI rule.

As reported in bug #57084, this logic produces incorrect results for C++ structs that inherit from other structs. This is because only the fields of the struct were examined, but enumerating RD->fields misses any fields in inherited C++ structs. This patch corrects that issue by adding appropriate logic to enumerate any included base structs.

Diff Detail

Event Timeline

asb created this revision.Aug 11 2022, 6:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 11 2022, 6:59 AM
asb requested review of this revision.Aug 11 2022, 6:59 AM
asb edited subscribers, added: cfe-commits; removed: llvm-commits.Aug 11 2022, 6:59 AM
inclyc added a subscriber: inclyc.Aug 11 2022, 7:01 AM
asb updated this revision to Diff 451915.Aug 11 2022, 10:58 AM
asb added reviewers: kito-cheng, craig.topper, reames.

Add test (I've pre-committed the current behaviour).

Now that update_cc_test_checks.py supports both --function-signature and --filter '^define ' I'd hoped I could massively improve the maintainability of the tests by using it. Unfortunately it seems that merging identical output under common CHECK lines isn't working as it does for update_llc_test_checks.py and the generated CHECK lines don't match against the function return type. It would definitely be good to address these issues and move all the RISC-V ABI tests to using update_cc_test_checks.py, but obviously I leave that for future work in favour of landing a fix quickly.

The previous lowering was broken (as opposed to being working but not in compliance with the official ABI). As such, I don't think there's any argument for providing a flag for the old behaviour (as sometimes happens with other targets after fixing ABI issues).

asb retitled this revision from [clang][RISCV][WIP] Fix incorrect ABI lowering for inherited structs with hard-float ABIs to [clang][RISCV] Fix incorrect ABI lowering for inherited structs under hard-float ABIs.Aug 11 2022, 11:00 AM
jrtc27 added inline comments.Aug 11 2022, 11:16 AM
clang/lib/CodeGen/TargetInfo.cpp
10986

With multiple inheritance this offset won't make sense, and it gets particularly fun with diamond virtual inheritance. This is a minefield.

And what about non-standard layout classes in general, like the simple ones that just have a vtable, not just ones that have virtual inheritance somwhere?

Remove the WIP note from the end of the description?

jrtc27 added inline comments.Aug 11 2022, 11:22 AM
clang/lib/CodeGen/TargetInfo.cpp
10986

(you at least need uint64_t BaseOffInBits = Layout.getBaseClassOffset(&B) and to add getContext().toCharUnitsFromBits(BaseOffInBits) like the field case, then there's the question of non-standard layout classes)

craig.topper added inline comments.Aug 11 2022, 11:35 AM
clang/lib/CodeGen/TargetInfo.cpp
10986

If it has a vtable wouldn't it have failed the getRecordArgABI check earlier? I think the copy constructor would not be trivial in that case.

jrtc27 added inline comments.Aug 11 2022, 11:41 AM
clang/lib/CodeGen/TargetInfo.cpp
10986

Quite possibly, I don't know all the details, just enough to be wary of ignoring it entirely

jrtc27 added inline comments.Aug 11 2022, 6:34 PM
clang/test/CodeGen/RISCV/riscv-abi.cpp
1

Not sure why you need -x c++ when it's a .cpp, that should be the default.

Also C++ tests belong in CodeGenCXX surely? Though I do see a lot of .cpp files in CodeGen...

asb edited the summary of this revision. (Show Details)Aug 11 2022, 10:41 PM
asb updated this revision to Diff 452090.Aug 11 2022, 11:55 PM

Add additional tests for diamond and virtual inheritance.

kito-cheng accepted this revision.Aug 17 2022, 2:42 AM

LGTM, result has compared with GCC for rv32gc/ilp32d and rv64gc/lp64d.

This revision is now accepted and ready to land.Aug 17 2022, 2:42 AM
jrtc27 accepted this revision.Aug 18 2022, 11:01 AM
craig.topper added inline comments.Aug 18 2022, 11:02 AM
clang/test/CodeGen/RISCV/riscv-abi.cpp
98

diamoned -> diamond

This revision was landed with ongoing or failed builds.Aug 19 2022, 12:32 PM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptAug 19 2022, 12:32 PM