<div dir="ltr">Hi all,<div><br></div><div>I noticed that given the following IR:</div><div><br></div><div>```</div><div>declare dso_local void @func()<br><br>@glob1 = dso_local unnamed_addr constant [2 x i32] [<br>  i32 0,<br>  i32 trunc (<br>      i64 sub (<br>        i64 ptrtoint (void ()* @func to i64),<br>        i64 ptrtoint ([2 x i32]* @glob1 to i64)<br>      ) to i32)<br>]<br></div><div>```</div><div><br></div><div>Compiling this with `./bin/llc /tmp/test2.ll -o - -relocation-model=static -data-sections=1 --mtriple=x86_64` gives the following assembly:</div><div><br></div><div>```</div><div>   .type       glob1,@object                   # @glob1<br>   .section        .rodata.cst8,"aM",@progbits,8<br>   .globl    glob1<br>   .p2align    2<br>glob1:<br>   .long   0                               # 0x0<br>   .long        func-glob1<br>   .size  glob1, 8<br></div><div>```</div><div><br></div><div>Despite passing `-data-sections=1`, the global does not have its own section name and is stored in `.section .rodata.cst8`. However, given the same size global and a static relocation model:</div><div><br></div><div>```</div><div>@glob2 = dso_local unnamed_addr constant [1 x i8*] [<br>  i8* bitcast ([1 x i8*]* @glob2 to i8*)<br>]<br></div><div>```</div><div><br></div><div>Using the same invocation returns:</div><div><br></div><div>```</div><div>    .type       glob2,@object                   # @glob2<br>   .section        .rodata.glob2,"a",@progbits<br>   .globl      glob2<br>   .p2align    3<br>glob2:<br>   .quad   glob2<br>   .size       glob2, 8<br></div><div>```</div><div><br></div><div>which does properly give `@glob2` its own section name (`.section .rodata.glob2`) and not stored in a mergeable const section. There seems to be some inconsistency between what section the globals are placed in (`.rodata` vs `.rodata.cstN`) despite them having the same size. For the case of `@glob1`, this is a problem if this symbol is dso_local/hidden and unused in its current DSO because if `-data-section` is used, then this symbol will not be collected by `--gc-sections` at link time because it's in a mergeable const section.</div><div><br></div><div>After some digging, it seems that the reason for this difference is because `@glob2` requires relocations according to `Constant::needsRelocation()` (because its initializer contains direct references to a global) whereas `@glob1` does not require relocations (because it stores a constant int and relative reference between two dso_local globals). The <a href="https://github.com/llvm/llvm-project/blob/b545667d0a4e8d3ca7d4789c3c4004b2816c1b84/llvm/lib/Target/TargetLoweringObjectFile.cpp#L285">path `@glob2` takes</a> does not allow it to be placed in a mergeable const section whereas `@glob1` can.</div><div><br></div><div>It seems that there are two issues with this logic:</div><div>1. Some globals that could be placed into mergeable sections don't ever have the chance to if `needsRelocation` returns false.</div><div>2. There are some globals placed in mergeable sections even if `-data-sections` is used if `needsRelocation` returns true.</div><div><br></div><div>I wanted to know if there was perhaps some intended reason for this (or if there were any errors in my logic)? If this was just a shortcoming, it seems that a potential solution for (1) would be to teach `needsRelocation` about the target relocation model, and a potential solution for (2) would be to return a ReadOnly section kind in `TargetLoweringObjectFile::getKindForGlobal()` if `-data-sections` is passed. Although these might just be kludges instead of a proper fix.</div><div><br></div><div>What do folks think?</div><div><br></div><div>Thanks,</div><div>Leonard</div></div>