diff options
author | Andrew Pinski <quic_apinski@quicinc.com> | 2025-08-07 11:44:21 -0700 |
---|---|---|
committer | Andrew Pinski <andrew.pinski@oss.qualcomm.com> | 2025-08-10 09:36:48 -0700 |
commit | 405f45aae779fe7694e8660cfa828f1cef58b101 (patch) | |
tree | 9596124039ca0d393ddd7aff5cfd565df63b7847 /gcc | |
parent | 59dbef0764c4897f6de2c864d6667618aaf53cf5 (diff) | |
download | gcc-405f45aae779fe7694e8660cfa828f1cef58b101.zip gcc-405f45aae779fe7694e8660cfa828f1cef58b101.tar.gz gcc-405f45aae779fe7694e8660cfa828f1cef58b101.tar.bz2 |
varasm: Ensure each variable in mergeable section is the entity size [PR121394]
Now there are mergeable sections which have an entity size, we can place
decls (constants) that are smaller in size in these sections.
An example is an `long double` which has a size of 12 bytes on i686 and is
placed in the 16 bytes shareable section.
For an example with the following C++ code:
```
std::initializer_list<long double> a = {0.3l};
```
We place the constant array in the .rodata.cst16 section but we don't add a padding to 16 bytes.
```
.section .rodata.cst16,"aM",@progbits,16
.align 16
.type _ZGR1a_, @object
.size _ZGR1a_, 12
_ZGR1a_:
.long -1717986918
.long -1717986919
.long 16381
.text
```
GAS has a workaround added to do the padding but other assemblers don't.
The gas workaround was added with https://sourceware.org/legacy-ml/binutils/2002-11/msg00615.html .
Now for the constant pool, GCC does emit a `.align` to padd out the size correctly.
This was done in r0-46282-gf41115930523b3.
The same padding should be done when emitting a variable contents when in a mergeable section.
This patch implements the padding and we now get an addition `.zero 4` which pads out the section.
Bootstrapped and tested on x86_64-linux-gnu.
PR middle-end/121394
gcc/ChangeLog:
* varasm.cc (assemble_variable_contents): Pad out
mergeable sections if needed.
(output_constant_pool_1): Change the padding to be explicit
zeroing for mergeable sections.
Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/varasm.cc | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/gcc/varasm.cc b/gcc/varasm.cc index 000ad9e..ee32cf1 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -2475,6 +2475,19 @@ assemble_variable_contents (tree decl, const char *name, else /* Leave space for it. */ assemble_zeros (tree_to_uhwi (DECL_SIZE_UNIT (decl))); + /* For mergeable section, make sure the section is zero filled up to + the entity size of the section. */ + if (in_section + && (in_section->common.flags & SECTION_MERGE) + && tree_fits_uhwi_p (DECL_SIZE_UNIT (decl)) + && ((in_section->common.flags & SECTION_ENTSIZE) + > tree_to_uhwi (DECL_SIZE_UNIT (decl)))) + { + unsigned HOST_WIDE_INT entsize, declsize; + entsize = (in_section->common.flags & SECTION_ENTSIZE); + declsize = tree_to_uhwi (DECL_SIZE_UNIT (decl)); + assemble_zeros (entsize - declsize); + } targetm.asm_out.decl_end (); } } @@ -4435,10 +4448,16 @@ output_constant_pool_1 (class constant_descriptor_rtx *desc, /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS sections have proper size. */ - if (align > GET_MODE_BITSIZE (desc->mode) - && in_section - && (in_section->common.flags & SECTION_MERGE)) - assemble_align (align); + if (in_section + && (in_section->common.flags & SECTION_MERGE) + && ((in_section->common.flags & SECTION_ENTSIZE) + > GET_MODE_SIZE (desc->mode))) + { + unsigned HOST_WIDE_INT entsize, constsize; + entsize = (in_section->common.flags & SECTION_ENTSIZE); + constsize = GET_MODE_SIZE (desc->mode); + assemble_zeros (entsize - constsize); + } #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY done: |