[llvm] [ConstantMerge] Only merge constant w/unnamed_addr (PR #124050)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 22 19:23:48 PST 2025


gulfemsavrun wrote:

This issue was discovered when we attempt to add `RelLookupTableConverterPass` to LTO prelink pass pipeline as in https://github.com/llvm/llvm-project/pull/124052. `RelLookupTableConverterPass` converts lookup tables to relative lookup tables to make them PIC-friendly.

The issue originally reported in https://reviews.llvm.org/D94355?id=315562#2717531, where we cannot build Clang with LTO when `RelLookupTableConverterPass` is added to LTO prelink passes. We disabled this pass in LTO prelink passes to avoid the issue at that time. But, we would like re-enable this pass in the LTO pipeline because we currently build with LTO and need our code to be PIC-friendly. Here's the issue that happens when we are building Clang with LTO.

There is a lookup table defined in https://github.com/llvm/llvm-project/blob/main/clang/lib/Basic/TargetInfo.cpp#L274:
```
const char *TargetInfo::getTypeFormatModifier(IntType T) {
  switch (T) {
  default: llvm_unreachable("not an integer!");
  case SignedChar:
  case UnsignedChar:     return "hh";
  case SignedShort:
  case UnsignedShort:    return "h";
  case SignedInt:
  case UnsignedInt:      return "";
  case SignedLong:
  case UnsignedLong:     return "l";
  case SignedLongLong:
  case UnsignedLongLong: return "ll";
  }
}
```

This lookup table is converted to a relative lookup table via `RelLookupTableConverter` pass.

There is a constant that is initialized in https://github.com/llvm/llvm-project/blob/main/llvm/lib/Support/Chrono.cpp#L18
```
const char llvm::detail::unit<std::ratio<3600>>::value[] = "h";
```

When built with LTO, ConstantMerge pass decides to merge constants that are initialized to "h". One of these constants are the elements of the the relative lookup table. This merge results in a relocation error with lld:

```
ld.lld: error: relocation R_X86_64_PC32 cannot be used against symbol 'llvm::detail::unit<std::ratio<60l, 1l>>::value'; recompile with -fPIC
>>> defined in lib/libclang-cpp.so.20.0git.lto.o
>>> referenced by ld-temp.o
>>>       
```

There are two ways that I can think of resolving this issue:
1) Change `ConstantMerge` pass as I implemented in this PR if we agree that this is kind of merge is a violation of C semantics and gcc and Clang should be consistent in their results. This requires guidance that has more expertise in C semantics.

2) `ConstantMerge` pass can have a side effect on `RelLookupTableConverter` pass, so add `RelLookupTableConverterPass` to post-link optimization pipeline after `ConstantMerge` as in https://github.com/llvm/llvm-project/pull/124053.

https://github.com/llvm/llvm-project/pull/124050


More information about the llvm-commits mailing list