Open DaMatrix opened 12 months ago
@llvm/issue-subscribers-backend-x86
Vectors in LLVM are defined to be tightly packed, so <2 x x86_fp80>
must have size 2*80 on the LLVM level at least.
https://godbolt.org/z/rcev7Ps1a shows that it does get interpreted this way by Clang at least in some cases. GCC uses the 16 byte representation.
Assuming we don't need ABI compatibility with GCC here, we should fix any cases where Clang assumes x86_fp80 in vectors to be padded.
Alright, I'd assumed that preserving the padding space between x86_fp80 elements would make sense, both for reasons of alignment (which is why the padding space exists in the first place), and the fact that vectors of all other element types (with the notable exception of OpenCL bool vectors) can be bitcast-ed/memcpy-ed directly to/from an appropriately sized array - wouldn't be possible if we omit the padding space.
I'll also assume that ABI compatibility isn't an issue here, and going through and removing padding space from these vectors on the clang side of things should be much easier than what I'd initially suggested. I'll give that a shot shortly.
While working on #66894 I've run into a lot of difficulties dealing with vectors of x86_fp80. These are "weird" in that they're the only vector element type which contains padding space (Compiler Explorer example which shows that the 80-bit vector elements are 16 bytes wide on x86-64, with 6 uninitialized padding bytes between them). However, much of the existing code for dealing with these vectors in both LLVM and clang seems to assume that all vectors are tightly packed without additional padding or that the padding space is initialized to zero, which results in unexpected behavior when attempting to do bitcast operations on them. Some examples of relevant broken code:
This test assumes that the padding space is initialized to zero:
https://github.com/llvm/llvm-project/blob/8768741800aae37a825864e2ee782484ed073ce9/clang/test/CodeGen/const-init.c#L138-L148
This assumes that there is no padding space at all (which triggers some assertions)%3B%0Ausing+int16_vec+%3D+short+attribute((vector_size(32)))%3B%0A%0Afp80_vec+bit_cast_vec(int16_vec+vec)+%7B%0A++++return+(fp80_vec)vec%3B%0A%7D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:37.545691906005224,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:clang170assert,deviceViewOpen:'1',filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'-emit-llvm+-march%3Dskylake',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+17.0.1+(assertions)+(Editor+%231)',t:'0')),k:50,l:'4',m:31.542857142857144,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+clang+17.0.1+(assertions)',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+clang+17.0.1+(assertions)+(Compiler+%231)',t:'0')),header:(),l:'4',m:68.45714285714286,n:'0',o:'',s:0,t:'0')),k:62.45430809399477,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)):
https://github.com/llvm/llvm-project/blob/f05f52ed4e74cf857bf07aef5dbd5d0861591a14/llvm/lib/IR/Instructions.cpp#L3747-L3750
This assumes there is no padding space at all:
https://github.com/llvm/llvm-project/blob/f05f52ed4e74cf857bf07aef5dbd5d0861591a14/llvm/test/Transforms/InstCombine/extractelement.ll#L606-L620
Fixing this will require some rather far-reaching changes, for example
CastInst::castIsValid
would need to accept aDataLayout
in order to determine the actual size of anx86_fp80
with padding.