[lld] [lld][LoongArch] Fix the handling of R_LARCH_PCALA64_* relocs (PR #73387)
Lu Weining via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 25 02:08:35 PST 2023
https://github.com/SixWeining updated https://github.com/llvm/llvm-project/pull/73387
>From 8dff73e7f11f928307ea7883bcdd8ea44cf31eac Mon Sep 17 00:00:00 2001
From: Weining Lu <luweining at loongson.cn>
Date: Sat, 25 Nov 2023 16:45:03 +0800
Subject: [PATCH 1/5] [lld][LoongArch] Partially fix the handling of
R_LARCH_PCALA64_* relocs
Defer the compution of `negativeB` because adding 0x1000 to original
`result` may yield a different `negativeB` value. Actually this issue
was first reported by @rui314 at https://reviews.llvm.org/D138135#4568594.
Note that even with this patch, the handling of R_LARCH_PCALA64_*
relocs are NOT totally correct, because current approach assumes those
four instructions (pcalau12i/addi.d/lu32i.d/lu52i.d) are in the same
4K-page which is not always true. It is possible to document this
assumption as a constraint in psABI in future. But at least this patch
is necessary.
See https://github.com/llvm/llvm-project/pull/71907 and
https://github.com/loongson-community/discussions/issues/17 for details.
---
lld/ELF/Arch/LoongArch.cpp | 3 +--
lld/test/ELF/loongarch-pc-aligned.s | 22 ++++++++++------------
2 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 1c3e015efc1649..9291ff14d674b6 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -157,10 +157,9 @@ uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) {
// result = page(dest) - page(pc) + 0x1000
uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pc);
bool negativeA = lo12(dest) > 0x7ff;
- bool negativeB = (result & 0x8000'0000) != 0;
-
if (negativeA)
result += 0x1000;
+ bool negativeB = (result & 0x8000'0000) != 0;
if (negativeA && !negativeB)
result -= 0x10000'0000;
else if (!negativeA && negativeB)
diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s
index e7950400a5c8c4..742ac502e79980 100644
--- a/lld/test/ELF/loongarch-pc-aligned.s
+++ b/lld/test/ELF/loongarch-pc-aligned.s
@@ -260,31 +260,29 @@
# EXTREME15-NEXT: lu32i.d $t0, -349526
# EXTREME15-NEXT: lu52i.d $t0, $t0, -1093
-## FIXME: Correct %pc64_lo20 should be 0xfffff (-1) and %pc64_hi12 should be 0xfff (-1), but current values are:
-## page delta = 0x0000000000000000, page offset = 0x888
+## page delta = 0xffffffff00000000, page offset = 0x888
## %pc_lo12 = 0x888 = -1912
## %pc_hi20 = 0x00000 = 0
-## %pc64_lo20 = 0x00000 = 0
-## %pc64_hi12 = 0x00000 = 0
+## %pc64_lo20 = 0xfffff = -1
+## %pc64_hi12 = 0xfff = -1
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x0000000012344888 --section-start=.text=0x0000000012345678 -o %t/extreme16
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme16 | FileCheck %s --check-prefix=EXTREME16
# EXTREME16: addi.d $t0, $zero, -1912
# EXTREME16-NEXT: pcalau12i $t1, 0
-# EXTREME16-NEXT: lu32i.d $t0, 0
-# EXTREME16-NEXT: lu52i.d $t0, $t0, 0
+# EXTREME16-NEXT: lu32i.d $t0, -1
+# EXTREME16-NEXT: lu52i.d $t0, $t0, -1
-## FIXME: Correct %pc64_lo20 should be 0x00000 (0) and %pc64_hi12 should be 0x000 (0), but current values are:
-## page delta = 0xffffffff80000000, page offset = 0x888
+## page delta = 0x0000000080000000, page offset = 0x888
## %pc_lo12 = 0x888 = -1912
## %pc_hi20 = 0x80000 = -524288
-## %pc64_lo20 = 0xfffff = -1
-## %pc64_hi12 = 0xfff = -1
+## %pc64_lo20 = 0xfffff = 0
+## %pc64_hi12 = 0xfff = 0
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x000071238ffff888 --section-start=.text=0x0000712310000678 -o %t/extreme17
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme17 | FileCheck %s --check-prefix=EXTREME17
# EXTREME17: addi.d $t0, $zero, -1912
# EXTREME17-NEXT: pcalau12i $t1, -524288
-# EXTREME17-NEXT: lu32i.d $t0, -1
-# EXTREME17-NEXT: lu52i.d $t0, $t0, -1
+# EXTREME17-NEXT: lu32i.d $t0, 0
+# EXTREME17-NEXT: lu52i.d $t0, $t0, 0
#--- a.s
.rodata
>From bd9849c41aa97d99a0eee8673d0d223039d5d4d5 Mon Sep 17 00:00:00 2001
From: Weining Lu <luweining at loongson.cn>
Date: Sun, 26 Nov 2023 22:46:54 +0800
Subject: [PATCH 2/5] Use the same logic as bfd and mold
---
lld/ELF/Arch/LoongArch.cpp | 89 ++++----------------------------------
1 file changed, 9 insertions(+), 80 deletions(-)
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 9291ff14d674b6..4bbf58242a0640 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -83,87 +83,16 @@ static uint32_t lo12(uint32_t val) { return val & 0xfff; }
// Calculate the adjusted page delta between dest and PC.
uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) {
- // Consider the large code model access pattern, of which the smaller code
- // models' access patterns are a subset:
- //
- // pcalau12i U, %foo_hi20(sym) ; b in [-0x80000, 0x7ffff]
- // addi.d T, zero, %foo_lo12(sym) ; a in [-0x800, 0x7ff]
- // lu32i.d T, %foo64_lo20(sym) ; c in [-0x80000, 0x7ffff]
- // lu52i.d T, T, %foo64_hi12(sym) ; d in [-0x800, 0x7ff]
- // {ldx,stx,add}.* dest, U, T
- //
- // Let page(pc) = 0xRRR'QQQQQ'PPPPP'000 and dest = 0xZZZ'YYYYY'XXXXX'AAA,
- // with RQ, P, ZY, X and A representing the respective bitfields as unsigned
- // integers. We have:
- //
- // page(dest) = 0xZZZ'YYYYY'XXXXX'000
- // - page(pc) = 0xRRR'QQQQQ'PPPPP'000
- // ----------------------------------
- // 0xddd'ccccc'bbbbb'000
- //
- // Now consider the above pattern's actual effects:
- //
- // page(pc) 0xRRR'QQQQQ'PPPPP'000
- // pcalau12i + 0xiii'iiiii'bbbbb'000
- // addi + 0xjjj'jjjjj'kkkkk'AAA
- // lu32i.d & lu52i.d + 0xddd'ccccc'00000'000
- // --------------------------------------------------
- // dest = U + T
- // = ((RQ<<32) + (P<<12) + i + (b<<12)) + (j + k + A + (cd<<32))
- // = (((RQ+cd)<<32) + i + j) + (((P+b)<<12) + k) + A
- // = (ZY<<32) + (X<<12) + A
- //
- // ZY<<32 = (RQ<<32)+(cd<<32)+i+j, X<<12 = (P<<12)+(b<<12)+k
- // cd<<32 = (ZY<<32)-(RQ<<32)-i-j, b<<12 = (X<<12)-(P<<12)-k
- //
- // where i and k are terms representing the effect of b's and A's sign
- // extension respectively.
- //
- // i = signed b < 0 ? -0x10000'0000 : 0
- // k = signed A < 0 ? -0x1000 : 0
- //
- // The j term is a bit complex: it represents the higher half of
- // sign-extended bits from A that are effectively lost if i == 0 but k != 0,
- // due to overwriting by lu32i.d & lu52i.d.
- //
- // j = signed A < 0 && signed b >= 0 ? 0x10000'0000 : 0
- //
- // The actual effect of the instruction sequence before the final addition,
- // i.e. our desired result value, is thus:
- //
- // result = (cd<<32) + (b<<12)
- // = (ZY<<32)-(RQ<<32)-i-j + (X<<12)-(P<<12)-k
- // = ((ZY<<32)+(X<<12)) - ((RQ<<32)+(P<<12)) - i - j - k
- // = page(dest) - page(pc) - i - j - k
- //
- // when signed A >= 0 && signed b >= 0:
- //
- // i = j = k = 0
- // result = page(dest) - page(pc)
- //
- // when signed A >= 0 && signed b < 0:
- //
- // i = -0x10000'0000, j = k = 0
- // result = page(dest) - page(pc) + 0x10000'0000
- //
- // when signed A < 0 && signed b >= 0:
- //
- // i = 0, j = 0x10000'0000, k = -0x1000
- // result = page(dest) - page(pc) - 0x10000'0000 + 0x1000
- //
- // when signed A < 0 && signed b < 0:
- //
- // i = -0x10000'0000, j = 0, k = -0x1000
- // result = page(dest) - page(pc) + 0x1000
+ // Compensating all the sign-extensions is a bit complicated.
+ // Just use the same logic as bfd and mold. Note that this algorithm assumes
+ // those four instructions (pcalau12i/addi.d/lu32i.d/lu52i.d) are in the same
+ // 4K-page. This assumption is expected to be documented as a constraint in
+ // psABI in future.
uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pc);
- bool negativeA = lo12(dest) > 0x7ff;
- if (negativeA)
- result += 0x1000;
- bool negativeB = (result & 0x8000'0000) != 0;
- if (negativeA && !negativeB)
- result -= 0x10000'0000;
- else if (!negativeA && negativeB)
- result += 0x10000'0000;
+ if (dest & 0x800)
+ result += 0x1000 - 0x1'0000'0000;
+ if (result & 0x8000'0000)
+ result += 0x1'0000'0000;
return result;
}
>From 96f6ab411d5308c77a73e0736b3f146c4307763b Mon Sep 17 00:00:00 2001
From: Weining Lu <luweining at loongson.cn>
Date: Sat, 2 Dec 2023 09:04:50 +0800
Subject: [PATCH 3/5] Address MaskRay's comments
---
lld/ELF/Arch/LoongArch.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 4bbf58242a0640..0c0648bcf48186 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -83,11 +83,9 @@ static uint32_t lo12(uint32_t val) { return val & 0xfff; }
// Calculate the adjusted page delta between dest and PC.
uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) {
- // Compensating all the sign-extensions is a bit complicated.
- // Just use the same logic as bfd and mold. Note that this algorithm assumes
- // those four instructions (pcalau12i/addi.d/lu32i.d/lu52i.d) are in the same
- // 4K-page. This assumption is expected to be documented as a constraint in
- // psABI in future.
+ // Compensate all the sign-extensions is a bit complicated. Just use the same
+ // logic as bfd and mold. Note that this algorithm assumes those four
+ // instructions (pcalau12i/addi.d/lu32i.d/lu52i.d) are in the same 4K-page.
uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pc);
if (dest & 0x800)
result += 0x1000 - 0x1'0000'0000;
>From ea96d51e668ca9a8ae80d9d7136fb649d8b6ea5e Mon Sep 17 00:00:00 2001
From: Weining Lu <luweining at loongson.cn>
Date: Thu, 7 Dec 2023 16:47:09 +0800
Subject: [PATCH 4/5] Add a testcase showing the incorrect result when
pcalau12i, addi.d, lu32i.d and lu52i.d are not in the same 4k-page
---
lld/test/ELF/loongarch-pc-aligned.s | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s
index 742ac502e79980..07d3c8656cd106 100644
--- a/lld/test/ELF/loongarch-pc-aligned.s
+++ b/lld/test/ELF/loongarch-pc-aligned.s
@@ -284,6 +284,17 @@
# EXTREME17-NEXT: lu32i.d $t0, 0
# EXTREME17-NEXT: lu52i.d $t0, $t0, 0
+## A case that pcalau12i, lu32i.d and lu52i.d are in different pages.
+# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x80000111 --section-start=.text=0xff8 -o %t/extreme18
+# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme18 | FileCheck %s --check-prefix=EXTREME18
+# EXTREME18: addi.d $t0, $zero, 273
+# EXTREME18-NEXT: pcalau12i $t1, -524288
+## FIXME: The relocation result is incorrect because lld uses seperate PCs of
+## each insn but not the PC of pcalau12i to calculate page delta. In this case
+## the correct result should be `lu32i.d $t0, 1`.
+# EXTREME18-NEXT: lu32i.d $t0, 0
+# EXTREME18-NEXT: lu52i.d $t0, $t0, 0
+
#--- a.s
.rodata
x:
>From 549f77ee2ea031e8f25c36929a3e568b36d59b5e Mon Sep 17 00:00:00 2001
From: Weining Lu <luweining at loongson.cn>
Date: Thu, 7 Dec 2023 19:33:26 +0800
Subject: [PATCH 5/5] Handle the case when pcalau12i, addi.d, lu32i.d and
lu52i.d are not in the same 4k-page
---
lld/ELF/Arch/LoongArch.cpp | 28 +++++++--
lld/ELF/InputSection.cpp | 10 ++--
lld/ELF/Target.h | 2 +-
lld/test/ELF/loongarch-pc-aligned.s | 88 +++++++++++++++--------------
4 files changed, 74 insertions(+), 54 deletions(-)
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 0c0648bcf48186..b36273605bf721 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -82,11 +82,29 @@ static uint64_t getLoongArchPage(uint64_t p) {
static uint32_t lo12(uint32_t val) { return val & 0xfff; }
// Calculate the adjusted page delta between dest and PC.
-uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) {
- // Compensate all the sign-extensions is a bit complicated. Just use the same
- // logic as bfd and mold. Note that this algorithm assumes those four
- // instructions (pcalau12i/addi.d/lu32i.d/lu52i.d) are in the same 4K-page.
- uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pc);
+uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type) {
+ // Note that if the sequence being relocated is `pcalau12i + addi.d + lu32i.d
+ // + lu52i.d`, they must be adjancent so that we can infer the PC of
+ // `pcalau12i` when calculating the page delta for the other two instructions
+ // (lu32i.d and lu52i.d). Compensate all the sign-extensions is a bit
+ // complicated. Just use psABI recommended algorithm.
+ uint64_t pcalau12i_pc;
+ switch (type) {
+ case R_LARCH_PCALA64_LO20:
+ case R_LARCH_GOT64_PC_LO20:
+ case R_LARCH_TLS_IE64_PC_LO20:
+ pcalau12i_pc = pc - 8;
+ break;
+ case R_LARCH_PCALA64_HI12:
+ case R_LARCH_GOT64_PC_HI12:
+ case R_LARCH_TLS_IE64_PC_HI12:
+ pcalau12i_pc = pc - 12;
+ break;
+ default:
+ pcalau12i_pc = pc;
+ break;
+ }
+ uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pcalau12i_pc);
if (dest & 0x800)
result += 0x1000 - 0x1'0000'0000;
if (result & 0x8000'0000)
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 6e972cf084cdc6..b1638f1218b770 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -714,8 +714,8 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
return sym.getGotVA() + a - p;
case R_LOONGARCH_GOT_PAGE_PC:
if (sym.hasFlag(NEEDS_TLSGD))
- return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p);
- return getLoongArchPageDelta(sym.getGotVA() + a, p);
+ return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p, type);
+ return getLoongArchPageDelta(sym.getGotVA() + a, p, type);
case R_MIPS_GOTREL:
return sym.getVA(a) - in.mipsGot->getGp(file);
case R_MIPS_GOT_GP:
@@ -765,7 +765,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
return 0;
}
case R_LOONGARCH_PAGE_PC:
- return getLoongArchPageDelta(sym.getVA(a), p);
+ return getLoongArchPageDelta(sym.getVA(a), p, type);
case R_PC:
case R_ARM_PCA: {
uint64_t dest;
@@ -800,7 +800,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
case R_PPC64_CALL_PLT:
return sym.getPltVA() + a - p;
case R_LOONGARCH_PLT_PAGE_PC:
- return getLoongArchPageDelta(sym.getPltVA() + a, p);
+ return getLoongArchPageDelta(sym.getPltVA() + a, p, type);
case R_PLT_GOTPLT:
return sym.getPltVA() + a - in.gotPlt->getVA();
case R_PPC32_PLTREL:
@@ -862,7 +862,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
case R_TLSGD_PC:
return in.got->getGlobalDynAddr(sym) + a - p;
case R_LOONGARCH_TLSGD_PAGE_PC:
- return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p);
+ return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p, type);
case R_TLSLD_GOTPLT:
return in.got->getVA() + in.got->getTlsIndexOff() + a - in.gotPlt->getVA();
case R_TLSLD_GOT:
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 6264ab1a3da74a..1bc5f98a692259 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -228,7 +228,7 @@ void addPPC64SaveRestore();
uint64_t getPPC64TocBase();
uint64_t getAArch64Page(uint64_t expr);
template <typename ELFT> void writeARMCmseImportLib();
-uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc);
+uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type);
void riscvFinalizeRelax(int passes);
void mergeRISCVAttributesSections();
void addArmInputSectionMappingSymbols();
diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s
index 07d3c8656cd106..0405961e5f74ec 100644
--- a/lld/test/ELF/loongarch-pc-aligned.s
+++ b/lld/test/ELF/loongarch-pc-aligned.s
@@ -75,8 +75,8 @@
## %pc64_hi12 = 0x444 = 1092
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x4443333334567111 --section-start=.text=0x0000000012345678 -o %t/extreme0
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme0 | FileCheck %s --check-prefix=EXTREME0
-# EXTREME0: addi.d $t0, $zero, 273
-# EXTREME0-NEXT: pcalau12i $t1, 139810
+# EXTREME0: pcalau12i $t1, 139810
+# EXTREME0-NEXT: addi.d $t0, $zero, 273
# EXTREME0-NEXT: lu32i.d $t0, 209715
# EXTREME0-NEXT: lu52i.d $t0, $t0, 1092
@@ -87,8 +87,8 @@
## %pc64_hi12 = 0x444 = 1092
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x4443333334567888 --section-start=.text=0x0000000012345678 -o %t/extreme1
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme1 | FileCheck %s --check-prefix=EXTREME1
-# EXTREME1: addi.d $t0, $zero, -1912
-# EXTREME1-NEXT: pcalau12i $t1, 139811
+# EXTREME1: pcalau12i $t1, 139811
+# EXTREME1-NEXT: addi.d $t0, $zero, -1912
# EXTREME1-NEXT: lu32i.d $t0, 209714
# EXTREME1-NEXT: lu52i.d $t0, $t0, 1092
@@ -99,8 +99,8 @@
## %pc64_hi12 = 0x444 = 1092
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x44433333abcde111 --section-start=.text=0x0000000012345678 -o %t/extreme2
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme2 | FileCheck %s --check-prefix=EXTREME2
-# EXTREME2: addi.d $t0, $zero, 273
-# EXTREME2-NEXT: pcalau12i $t1, -419431
+# EXTREME2: pcalau12i $t1, -419431
+# EXTREME2-NEXT: addi.d $t0, $zero, 273
# EXTREME2-NEXT: lu32i.d $t0, 209716
# EXTREME2-NEXT: lu52i.d $t0, $t0, 1092
@@ -111,8 +111,8 @@
## %pc64_hi12 = 0x444 = 1092
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x44433333abcde888 --section-start=.text=0x0000000012345678 -o %t/extreme3
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme3 | FileCheck %s --check-prefix=EXTREME3
-# EXTREME3: addi.d $t0, $zero, -1912
-# EXTREME3-NEXT: pcalau12i $t1, -419430
+# EXTREME3: pcalau12i $t1, -419430
+# EXTREME3-NEXT: addi.d $t0, $zero, -1912
# EXTREME3-NEXT: lu32i.d $t0, 209715
# EXTREME3-NEXT: lu52i.d $t0, $t0, 1092
@@ -123,8 +123,8 @@
## %pc64_hi12 = 0x444 = 1092
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaa34567111 --section-start=.text=0x0000000012345678 -o %t/extreme4
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme4 | FileCheck %s --check-prefix=EXTREME4
-# EXTREME4: addi.d $t0, $zero, 273
-# EXTREME4-NEXT: pcalau12i $t1, 139810
+# EXTREME4: pcalau12i $t1, 139810
+# EXTREME4-NEXT: addi.d $t0, $zero, 273
# EXTREME4-NEXT: lu32i.d $t0, -349526
# EXTREME4-NEXT: lu52i.d $t0, $t0, 1092
@@ -135,8 +135,8 @@
## %pc64_hi12 = 0x444 = 1092
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaa34567888 --section-start=.text=0x0000000012345678 -o %t/extreme5
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme5 | FileCheck %s --check-prefix=EXTREME5
-# EXTREME5: addi.d $t0, $zero, -1912
-# EXTREME5-NEXT: pcalau12i $t1, 139811
+# EXTREME5: pcalau12i $t1, 139811
+# EXTREME5-NEXT: addi.d $t0, $zero, -1912
# EXTREME5-NEXT: lu32i.d $t0, -349527
# EXTREME5-NEXT: lu52i.d $t0, $t0, 1092
@@ -147,8 +147,8 @@
## %pc64_hi12 = 0x444 = 1092
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaaabcde111 --section-start=.text=0x0000000012345678 -o %t/extreme6
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme6 | FileCheck %s --check-prefix=EXTREME6
-# EXTREME6: addi.d $t0, $zero, 273
-# EXTREME6-NEXT: pcalau12i $t1, -419431
+# EXTREME6: pcalau12i $t1, -419431
+# EXTREME6-NEXT: addi.d $t0, $zero, 273
# EXTREME6-NEXT: lu32i.d $t0, -349525
# EXTREME6-NEXT: lu52i.d $t0, $t0, 1092
@@ -159,8 +159,8 @@
## %pc64_hi12 = 0x444 = 1092
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaaabcde888 --section-start=.text=0x0000000012345678 -o %t/extreme7
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme7 | FileCheck %s --check-prefix=EXTREME7
-# EXTREME7: addi.d $t0, $zero, -1912
-# EXTREME7-NEXT: pcalau12i $t1, -419430
+# EXTREME7: pcalau12i $t1, -419430
+# EXTREME7-NEXT: addi.d $t0, $zero, -1912
# EXTREME7-NEXT: lu32i.d $t0, -349526
# EXTREME7-NEXT: lu52i.d $t0, $t0, 1092
@@ -171,8 +171,8 @@
## %pc64_hi12 = 0xbbb = -1093
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb3333334567111 --section-start=.text=0x0000000012345678 -o %t/extreme8
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme8 | FileCheck %s --check-prefix=EXTREME8
-# EXTREME8: addi.d $t0, $zero, 273
-# EXTREME8-NEXT: pcalau12i $t1, 139810
+# EXTREME8: pcalau12i $t1, 139810
+# EXTREME8-NEXT: addi.d $t0, $zero, 273
# EXTREME8-NEXT: lu32i.d $t0, 209715
# EXTREME8-NEXT: lu52i.d $t0, $t0, -1093
@@ -183,8 +183,8 @@
## %pc64_hi12 = 0xbbb = -1093
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb3333334567888 --section-start=.text=0x0000000012345678 -o %t/extreme9
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme9 | FileCheck %s --check-prefix=EXTREME9
-# EXTREME9: addi.d $t0, $zero, -1912
-# EXTREME9-NEXT: pcalau12i $t1, 139811
+# EXTREME9: pcalau12i $t1, 139811
+# EXTREME9-NEXT: addi.d $t0, $zero, -1912
# EXTREME9-NEXT: lu32i.d $t0, 209714
# EXTREME9-NEXT: lu52i.d $t0, $t0, -1093
@@ -195,8 +195,8 @@
## %pc64_hi12 = 0xbbb = -1093
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb33333abcde111 --section-start=.text=0x0000000012345678 -o %t/extreme10
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme10 | FileCheck %s --check-prefix=EXTREME10
-# EXTREME10: addi.d $t0, $zero, 273
-# EXTREME10-NEXT: pcalau12i $t1, -419431
+# EXTREME10: pcalau12i $t1, -419431
+# EXTREME10-NEXT: addi.d $t0, $zero, 273
# EXTREME10-NEXT: lu32i.d $t0, 209716
# EXTREME10-NEXT: lu52i.d $t0, $t0, -1093
@@ -207,8 +207,8 @@
## %pc64_hi12 = 0xbbb = -1093
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb33333abcde888 --section-start=.text=0x0000000012345678 -o %t/extreme11
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme11 | FileCheck %s --check-prefix=EXTREME11
-# EXTREME11: addi.d $t0, $zero, -1912
-# EXTREME11-NEXT: pcalau12i $t1, -419430
+# EXTREME11: pcalau12i $t1, -419430
+# EXTREME11-NEXT: addi.d $t0, $zero, -1912
# EXTREME11-NEXT: lu32i.d $t0, 209715
# EXTREME11-NEXT: lu52i.d $t0, $t0, -1093
@@ -219,8 +219,8 @@
## %pc64_hi12 = 0xbbb = -1093
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaa34567111 --section-start=.text=0x0000000012345678 -o %t/extreme12
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme12 | FileCheck %s --check-prefix=EXTREME12
-# EXTREME12: addi.d $t0, $zero, 273
-# EXTREME12-NEXT: pcalau12i $t1, 139810
+# EXTREME12: pcalau12i $t1, 139810
+# EXTREME12-NEXT: addi.d $t0, $zero, 273
# EXTREME12-NEXT: lu32i.d $t0, -349526
# EXTREME12-NEXT: lu52i.d $t0, $t0, -1093
@@ -231,8 +231,8 @@
## %pc64_hi12 = 0xbbb = -1093
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaa34567888 --section-start=.text=0x0000000012345678 -o %t/extreme13
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme13 | FileCheck %s --check-prefix=EXTREME13
-# EXTREME13: addi.d $t0, $zero, -1912
-# EXTREME13-NEXT: pcalau12i $t1, 139811
+# EXTREME13: pcalau12i $t1, 139811
+# EXTREME13-NEXT: addi.d $t0, $zero, -1912
# EXTREME13-NEXT: lu32i.d $t0, -349527
# EXTREME13-NEXT: lu52i.d $t0, $t0, -1093
@@ -243,8 +243,8 @@
## %pc64_hi12 = 0xbbb = -1093
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaaabcde111 --section-start=.text=0x0000000012345678 -o %t/extreme14
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme14 | FileCheck %s --check-prefix=EXTREME14
-# EXTREME14: addi.d $t0, $zero, 273
-# EXTREME14-NEXT: pcalau12i $t1, -419431
+# EXTREME14: pcalau12i $t1, -419431
+# EXTREME14-NEXT: addi.d $t0, $zero, 273
# EXTREME14-NEXT: lu32i.d $t0, -349525
# EXTREME14-NEXT: lu52i.d $t0, $t0, -1093
@@ -255,8 +255,8 @@
## %pc64_hi12 = 0xbbb = -1093
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaaabcde888 --section-start=.text=0x0000000012345678 -o %t/extreme15
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme15 | FileCheck %s --check-prefix=EXTREME15
-# EXTREME15: addi.d $t0, $zero, -1912
-# EXTREME15-NEXT: pcalau12i $t1, -419430
+# EXTREME15: pcalau12i $t1, -419430
+# EXTREME15-NEXT: addi.d $t0, $zero, -1912
# EXTREME15-NEXT: lu32i.d $t0, -349526
# EXTREME15-NEXT: lu52i.d $t0, $t0, -1093
@@ -267,8 +267,8 @@
## %pc64_hi12 = 0xfff = -1
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x0000000012344888 --section-start=.text=0x0000000012345678 -o %t/extreme16
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme16 | FileCheck %s --check-prefix=EXTREME16
-# EXTREME16: addi.d $t0, $zero, -1912
-# EXTREME16-NEXT: pcalau12i $t1, 0
+# EXTREME16: pcalau12i $t1, 0
+# EXTREME16-NEXT: addi.d $t0, $zero, -1912
# EXTREME16-NEXT: lu32i.d $t0, -1
# EXTREME16-NEXT: lu52i.d $t0, $t0, -1
@@ -279,20 +279,22 @@
## %pc64_hi12 = 0xfff = 0
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x000071238ffff888 --section-start=.text=0x0000712310000678 -o %t/extreme17
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme17 | FileCheck %s --check-prefix=EXTREME17
-# EXTREME17: addi.d $t0, $zero, -1912
-# EXTREME17-NEXT: pcalau12i $t1, -524288
+# EXTREME17: pcalau12i $t1, -524288
+# EXTREME17-NEXT: addi.d $t0, $zero, -1912
# EXTREME17-NEXT: lu32i.d $t0, 0
# EXTREME17-NEXT: lu52i.d $t0, $t0, 0
## A case that pcalau12i, lu32i.d and lu52i.d are in different pages.
+## page delta = 0x0000000080000000, page offset = 0x123
+## %pc_lo12 = 0x111 = 273
+## %pc_hi20 = 0x80000 = -524288
+## %pc64_lo20 = 0x00001 = 1
+## %pc64_hi12 = 0x000 = 0
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x80000111 --section-start=.text=0xff8 -o %t/extreme18
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme18 | FileCheck %s --check-prefix=EXTREME18
-# EXTREME18: addi.d $t0, $zero, 273
-# EXTREME18-NEXT: pcalau12i $t1, -524288
-## FIXME: The relocation result is incorrect because lld uses seperate PCs of
-## each insn but not the PC of pcalau12i to calculate page delta. In this case
-## the correct result should be `lu32i.d $t0, 1`.
-# EXTREME18-NEXT: lu32i.d $t0, 0
+# EXTREME18: pcalau12i $t1, -524288
+# EXTREME18-NEXT: addi.d $t0, $zero, 273
+# EXTREME18-NEXT: lu32i.d $t0, 1
# EXTREME18-NEXT: lu52i.d $t0, $t0, 0
#--- a.s
@@ -312,7 +314,7 @@ x:
.text
.global _start
_start:
- addi.d $t0, $zero, %pc_lo12(x)
pcalau12i $t1, %pc_hi20(x)
+ addi.d $t0, $zero, %pc_lo12(x)
lu32i.d $t0, %pc64_lo20(x)
lu52i.d $t0, $t0, %pc64_hi12(x)
More information about the llvm-commits
mailing list