[llvm] [ConstantMerge] Only merge constant w/unnamed_addr (PR #124050)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 23 15:14:16 PST 2025
gulfemsavrun wrote:
> For the C semantics issue, I think we'd have to add a new unnamed_addr variant, not change the meaning of the existing one. See #63628 for related issue (though I feel like I saw a longer discussion on this somewhere else...)
>
> I don't think your actual problem is really related though. LLVM shouldn't do transforms that ultimately result in a relocation error. Can you explain in more detail why it happens, maybe with a minimal test case? I'm not sure I understand where the problem originates.
Here's a small reproducer to explain the issue with `RelLookupTableConverterPass`:
a.c:
```
const char *getTypeFormatModifier(int T) {
switch (T) {
case 0:
case 1: return "hh";
case 2:
case 3: return "h";
}
return "";
}
```
b.c:
```
extern const char value[] = "h";
```
```
~/build/stage1/bin/clang -fPIC -flto -O3 -c a.cc -o a.o
~/build/stage1/bin/clang -fPIC -flto -O3 -c b.cc -o b.o
~/build/stage1/bin/clang -fPIC -flto -O3 -fuse-ld=/usr/local/google/home/gulfem/build/stage1/bin/ld.lld -shared -o output-lto a.o b.o
```
We convert switch lookup table into a relative lookup table, where we out relative offsets into the relative lookup table.
; *** IR Dump Before RelLookupTableConverterPass on [module] ***
```
@.str = private unnamed_addr constant [3 x i8] c"hh\00", align 1
@.str.1 = private unnamed_addr constant [2 x i8] c"h\00", align 1
@.str.2 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@switch.table._Z21getTypeFormatModifieri = private unnamed_addr constant [4 x ptr] [ptr @.str, ptr @.str, ptr @.str.1, ptr @.str.1], align 8
```
; *** IR Dump After RelLookupTableConverterPass on [module] ***
```
@.str = private unnamed_addr constant [3 x i8] c"hh\00", align 1
@.str.1 = private unnamed_addr constant [2 x i8] c"h\00", align 1
@.str.2 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@switch.table._Z21getTypeFormatModifieri.rel = private unnamed_addr constant [4 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @.str to i64), i64 ptrtoint (ptr @switch.table._Z21getTypeFormatModifieri.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @.str to i64), i64 ptrtoint (ptr @switch.table._Z21getTypeFormatModifieri.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @.str.1 to i64), i64 ptrtoint (ptr @switch.table._Z21getTypeFormatModifieri.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @.str.1 to i64), i64 ptrtoint (ptr @switch.table._Z21getTypeFormatModifieri.rel to i64)) to i32)], align 4
```
Later in `ConstantMerge` pass decides to merge `@.str.1 = private unnamed_addr constant [2 x i8] c"h\00"` into `@value = local_unnamed_addr constant [2 x i8] c"h\00"`
```
@.str = private unnamed_addr constant [3 x i8] c"hh\00", align 1
@.str.2 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@switch.table._Z21getTypeFormatModifieri.rel = private unnamed_addr constant [4 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @.str to i64), i64 ptrtoint (ptr @switch.table._Z21getTypeFormatModifieri.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @.str to i64), i64 ptrtoint (ptr @switch.table._Z21getTypeFormatModifieri.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @value to i64), i64 ptrtoint (ptr @switch.table._Z21getTypeFormatModifieri.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @value to i64), i64 ptrtoint (ptr @switch.table._Z21getTypeFormatModifieri.rel to i64)) to i32)], align 4
@value = local_unnamed_addr constant [2 x i8] c"h\00", align 1
```
We apply `RelLookupTableConverterPass` so that the relative lookup table can be put into `.rodata` section. But, in this case the relative lookup table was put into `.data.rel.ro` section because one of its values points to `local_unnamed_addr`.
```
ld.lld: error: relocation R_X86_64_PC32 cannot be used against symbol 'value'; recompile with -fPIC
>>> defined in output-lto.lto.o
>>> referenced by ld-temp.o
>>> output-lto.lto.o:(.data.rel.ro..Lswitch.table._Z21getTypeFormatModifieri.rel+0x8)
```
https://github.com/llvm/llvm-project/pull/124050
More information about the llvm-commits
mailing list