[PATCH] D65234: [CodeGen]: don't treat structures returned in registers as memory inputs
Alexander Potapenko via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 26 05:39:35 PDT 2019
glider marked 2 inline comments as done.
glider added inline comments.
================
Comment at: clang/lib/CodeGen/CGStmt.cpp:1989
std::vector<llvm::Value*> Args;
+ std::vector<bool> ResultTypeRequiresCast;
----------------
nickdesaulniers wrote:
> Are we able to use something other than `std::vector<bool>` here from ADT?
> http://llvm.org/docs/ProgrammersManual.html#bit-storage-containers-bitvector-sparsebitvector
I don't think `std::vector<bool>` is a bottleneck here, but since it might be deprecated someday let's just not use it.
================
Comment at: clang/lib/CodeGen/CGStmt.cpp:2287
assert(RegResults.size() == ResultRegDests.size());
+ assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
----------------
efriedma wrote:
> Not "=="?
Turns out ResultRegDests can be also extended by `addReturnRegisterOutputs` above (line 2122), so no.
I've added a comment to clarify that.
================
Comment at: clang/lib/CodeGen/CGStmt.cpp:2325
+ Dest = MakeAddrLValue(
+ A, getContext().getIntTypeForBitwidth(Size, /*Signed*/ false));
+ }
----------------
efriedma wrote:
> Will this work if the struct is an unusual size, like `sizeof(struct s) == 3` or `sizeof(struct s) == 32`? (3 is unlikely to show up in real code, but 32 could correspond to a vector register.)
For a 3-byte struct this works as follows: a 3-byte structure is allocated on the stack with alignment 2, then the assembly returns a 4-byte integer that's written to that 3-byte structure.
This conforms to what GCC does, and I think it's legal to let the assembly write more than a structure size here, as the corresponding register size is bigger (i.e. it's a bug in the C code, not Clang).
For a 32-bit struct we crash now, whereas GCC reports an "impossible constraint in ‘asm’"
It's interesting that the crash happens in the frontend, i.e. it's somehow knows the maximum possible size for the register operand.
We can check that `getContext().getIntTypeForBitwidth(Size, /*Signed*/ false)` is a nonnull type to prevent the crashes.
================
Comment at: clang/test/CodeGen/PR42672.c:50
+ struct {
+ long long int v1, v2, v3, v4;
+ } str;
----------------
The acceptable size actually depends on the target platform. Not sure we can test for all of them, and we'll probably need to restrict this test to e.g. x86
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D65234/new/
https://reviews.llvm.org/D65234
More information about the cfe-commits
mailing list