| Issue |
171855
|
| Summary |
Global object alignment diverges from MSVC
|
| Labels |
backend:X86,
diverges-from:msvc
|
| Assignees |
|
| Reporter |
e-kud
|
Let's consider the following code
```
template<unsigned SIZE, typename T>
class Obj {
public:
Obj() = default;
T mm[SIZE];
static const Obj<SIZE, T>& g() {
static const Obj<SIZE, T> _g = Obj<SIZE, T>();
return _g;
}
};
template<unsigned SIZE>
__declspec(noinline) const Obj<SIZE, char> &foo() {
return Obj<SIZE, char>::g();
}
int main() {
return foo<128>().mm[0];
}
```
Here we introduce a global object with an array inside.
When compiled with `cl test.cpp` we see the following in `llvm-readobj --all test.obj`
```
...
Section {
Number: 12
Name: .bss (2E 62 73 73 00 00 00 00)
VirtualSize: 0x0
VirtualAddress: 0x0
RawDataSize: 128
PointerToRawData: 0x0
PointerToRelocations: 0x0
PointerToLineNumbers: 0x0
RelocationCount: 0
LineNumberCount: 0
Characteristics [ (0xC0501080)
IMAGE_SCN_ALIGN_16BYTES (0x500000)
IMAGE_SCN_CNT_UNINITIALIZED_DATA (0x80)
IMAGE_SCN_LNK_COMDAT (0x1000)
IMAGE_SCN_MEM_READ (0x40000000)
IMAGE_SCN_MEM_WRITE (0x80000000)
]
}
...
Symbol {
Name: ?_g@?1??g@?$Obj@$0IA@D@@SAAEBV2@XZ@4V2@B
Value: 0
Section: .bss (12)
BaseType: Null (0x0)
ComplexType: Null (0x0)
StorageClass: External (0x2)
AuxSymbolCount: 0
}
...
```
So the symbol is 16 bytes aligned.
However, when compiled with `clang++ -fms-extensions -O3 -target x86_64-pc-windows-msvc test.cpp -c` we see no alignment
```
...
Section {
Number: 6
Name: .rdata (2E 72 64 61 74 61 00 00)
VirtualSize: 0x0
VirtualAddress: 0x0
RawDataSize: 128
PointerToRawData: 0x1B1
PointerToRelocations: 0x0
PointerToLineNumbers: 0x0
RelocationCount: 0
LineNumberCount: 0
Characteristics [ (0x40101040)
IMAGE_SCN_ALIGN_1BYTES (0x100000)
IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
IMAGE_SCN_LNK_COMDAT (0x1000)
IMAGE_SCN_MEM_READ (0x40000000)
]
}
...
Symbol {
Name: ?_g@?1??g@?$Obj@$0IA@D@@SAAEBV2@XZ@4V2@B
Value: 0
Section: .rdata (6)
BaseType: Null (0x0)
ComplexType: Null (0x0)
StorageClass: External (0x2)
AuxSymbolCount: 0
}
...
```
The problem here is that the code compiled with MSVC cannot work with Clang compiled binaries due to misalignment as MSVC generates instructions for aligned memory access, when in reality it is not aligned if it is in Clang compiled binaries. (Sorry, I don't have a small reproducer for runtime failure).
MSVC doesn't have any align attributes in assembly. Through a set of experiments I figured out that MSVC aligns objects by following rules:
1) Size `>=64` align to 16 bytes
2) Size `>=8` align to 8 bytes
3) Size `>=2` align to 4 bytes
4) Otherwise align to 1 byte.
I'm not sure what is the better place to fix it. I'll submit a PR to fix it in assembly emission:
1) It allows to save compatibility between binaries of earlier and future versions compiled by clang
2) Provides MSVC-Clang compatibility.
If we change it in the FE, binaries will be incompatible between clang version, i.e. breaking change.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs