Closed sidtver closed 1 year ago
@llvm/issue-subscribers-clang-codegen
clang has code to fill in padding of structs, if we want to... we just avoid it when possible for the sake of making the IR more readable. See CGRecordLowering::insertPadding .
We avoid loads and stores of struct types for other reasons. Mostly related to optimizations. The SelectionDAG doesn't really handle them efficiently. And as a consequence of us avoiding them, IR optimizations don't really handle them well either.
If you have other questions about the current design, you can start a thread on Discourse (https://discourse.llvm.org). A bugtracker isn't really a good place for that sort of thing.
Thank you for the information provided. This "issue" is now complete, I didn't know about Discourse before. I will think about it and maybe ask a revised question in Discourse.
Lets consider simple example in C-language.
There are two circumstances. (1) The llvm-IR hasn’t unions in its type system. It has only structs. (2) Load and store operations for structs copy only struct’s fields, not whole memory area of struct as in C/C++.
So lets see llvm-IR of the example for x86.
Clang transforms union
S3
into the struct with name%union.S3
. Only the first fieldS3.x
was saved, and the second fieldS3.y
was deleted.Copy operation from
B
toA
was made as a call of intrinsic@llvm.memcpy.*
It is an imposible to load value ofB
and store the loaded value toA
. Because in this case (in x86-backend) the fieldS3.x.b
will be copied as 32-bit value. So high 32 bits ofS3.y.b
will be lost. It is easy to check.The x86-ABI says to pass struct’s values by reference:
That is why there is no copy operation in IR for formal parameters’s values in call of function
g
.Now lets see llvm-IR for MIPS (mips64el).
The Clang frontend split struct
S3
into threei64
values. It was made for parameters of functionsg
. Also access operations to struct fields are transformed to bit-operations.All together (1) and (2) force to apply very low-level target dependent (stack and registers layer) transformation in Clang frontend. It causes unnatural transformation in IR for targets with direct transport of struct values. It causes premature optimization in single frontend (Clang) when targets backends are possible to make parameters’s transportation in valid way. And a uniform optimization (MachineInstruction or llvm-IR stage) is needed for all frontends. Not only for Clang.
As an alternative I see a possible change of union’s lowering as follows. It may be a llvm first-time pass or internal clang-AST to llvm-IR functionality. Suppose for all structures with indirect paddings was made an embeding of additional fields. For example lets substitute
into
After such transformation it becames possible to use load/store operations for coping and to use direct passing of parameters with struct type in IR.