summaryrefslogtreecommitdiffstats
path: root/llvm/test/MC/RISCV
diff options
context:
space:
mode:
authorJames Clarke <jrtc27@jrtc27.com>2020-01-23 02:05:46 +0000
committerHans Wennborg <hans@chromium.org>2020-01-23 18:27:29 +0100
commit8634a82910eba78279a69fcba0925d3a602a0563 (patch)
treea7dcdecf87df7a4ce0bee5d139eecee03d12b4d7 /llvm/test/MC/RISCV
parent5d37ce7e19c9961b45bef2f2f66805f4a8f02daf (diff)
downloadbcm5719-llvm-8634a82910eba78279a69fcba0925d3a602a0563.tar.gz
bcm5719-llvm-8634a82910eba78279a69fcba0925d3a602a0563.zip
[RISCV] Fix evaluating %pcrel_lo against global and weak symbols
Summary: Previously, we would erroneously turn %pcrel_lo(label), where label has a %pcrel_hi against a weak symbol, into %pcrel_lo(label + offset), as evaluatePCRelLo would believe the target independent logic was going to fold it. Moreover, even if that were fixed, shouldForceRelocation lacks an MCAsmLayout and thus cannot evaluate the %pcrel_hi fixup to a value and check the symbol, so we would then erroneously constant-fold the %pcrel_lo whilst leaving the %pcrel_hi intact. After D72197, this same sequence also occurs for symbols with global binding, which is triggered in real-world code. Instead, as discussed in D71978, we introduce a new FKF_IsTarget flag to avoid these kinds of issues. All the resolution logic happens in one place, with no coordination required between RISCAsmBackend and RISCVMCExpr to ensure they implement the same logic twice. Although the implementation of %pcrel_hi can be left as target independent, we make it target dependent to ensure that they are handled identically to %pcrel_lo, otherwise we risk one of them being constant folded but the other being preserved. This also allows us to properly support fixup pairs where the instructions are in different fragments. Reviewers: asb, lenary, efriedma Reviewed By: efriedma Subscribers: arichardson, hiraditya, rbar, johnrusso, simoncook, sabuasal, niosHD, kito-cheng, shiva0217, MaskRay, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, Jim, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73211 (cherry picked from commit 3f5976c97dbfefb4669abcf968bd79a9a64c18e0)
Diffstat (limited to 'llvm/test/MC/RISCV')
-rw-r--r--llvm/test/MC/RISCV/pcrel-fixups.s74
-rw-r--r--llvm/test/MC/RISCV/pcrel-lo12-invalid.s2
-rw-r--r--llvm/test/MC/RISCV/rv32i-aliases-valid.s7
-rw-r--r--llvm/test/MC/RISCV/rv32i-valid.s7
-rw-r--r--llvm/test/MC/RISCV/rv64i-aliases-valid.s8
5 files changed, 81 insertions, 17 deletions
diff --git a/llvm/test/MC/RISCV/pcrel-fixups.s b/llvm/test/MC/RISCV/pcrel-fixups.s
index 1025988967a..f4f9e2c57a0 100644
--- a/llvm/test/MC/RISCV/pcrel-fixups.s
+++ b/llvm/test/MC/RISCV/pcrel-fixups.s
@@ -12,11 +12,12 @@
# RUN: | FileCheck --check-prefix RELAX %s
# Fixups for %pcrel_hi / %pcrel_lo can be evaluated within a section,
-# regardless of the fragment containing the target address.
+# regardless of the fragment containing the target address, provided symbol
+# binding allows it.
function:
.Lpcrel_label1:
- auipc a0, %pcrel_hi(other_function)
+ auipc a0, %pcrel_hi(local_function)
addi a1, a0, %pcrel_lo(.Lpcrel_label1)
# NORELAX: auipc a0, 0
# NORELAX-NOT: R_RISCV
@@ -24,7 +25,7 @@ function:
# NORELAX-NOT: R_RISCV
# RELAX: auipc a0, 0
-# RELAX: R_RISCV_PCREL_HI20 other_function
+# RELAX: R_RISCV_PCREL_HI20 local_function
# RELAX: R_RISCV_RELAX *ABS*
# RELAX: addi a1, a0, 0
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label1
@@ -32,7 +33,7 @@ function:
.p2align 2 # Cause a new fragment be emitted here
.Lpcrel_label2:
- auipc a0, %pcrel_hi(other_function)
+ auipc a0, %pcrel_hi(local_function)
addi a1, a0, %pcrel_lo(.Lpcrel_label2)
# NORELAX: auipc a0, 0
# NORELAX-NOT: R_RISCV
@@ -40,13 +41,72 @@ function:
# NORELAX-NOT: R_RISCV
# RELAX: auipc a0, 0
-# RELAX: R_RISCV_PCREL_HI20 other_function
+# RELAX: R_RISCV_PCREL_HI20 local_function
# RELAX: R_RISCV_RELAX *ABS*
# RELAX: addi a1, a0, 0
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label2
# RELAX: R_RISCV_RELAX *ABS*
- .type other_function,@function
-other_function:
+ .type local_function,@function
+local_function:
ret
+# Check we correctly evaluate when fixups are in different fragments
+
+.Lpcrel_label3:
+ auipc a0, %pcrel_hi(local_function)
+ .p2align 2 # Cause a new fragment be emitted here
+ addi a1, a0, %pcrel_lo(.Lpcrel_label3)
+# NORELAX: auipc a0, 0
+# NORELAX-NOT: R_RISCV
+# NORELAX: addi a1, a0, -4
+# NORELAX-NOT: R_RISCV
+
+# RELAX: auipc a0, 0
+# RELAX: R_RISCV_PCREL_HI20 local_function
+# RELAX: R_RISCV_RELAX *ABS*
+# RELAX: addi a1, a0, 0
+# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label3
+# RELAX: R_RISCV_RELAX *ABS*
+
+# Check handling of symbol binding.
+
+.Lpcrel_label4:
+ auipc a0, %pcrel_hi(global_function)
+ addi a1, a0, %pcrel_lo(.Lpcrel_label4)
+# NORELAX: auipc a0, 0
+# NORELAX: R_RISCV_PCREL_HI20 global_function
+# NORELAX: addi a1, a0, 0
+# NORELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label4
+
+# RELAX: auipc a0, 0
+# RELAX: R_RISCV_PCREL_HI20 global_function
+# RELAX: R_RISCV_RELAX *ABS*
+# RELAX: addi a1, a0, 0
+# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label4
+# RELAX: R_RISCV_RELAX *ABS*
+
+.Lpcrel_label5:
+ auipc a0, %pcrel_hi(weak_function)
+ addi a1, a0, %pcrel_lo(.Lpcrel_label5)
+# NORELAX: auipc a0, 0
+# NORELAX: R_RISCV_PCREL_HI20 weak_function
+# NORELAX: addi a1, a0, 0
+# NORELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label5
+
+# RELAX: auipc a0, 0
+# RELAX: R_RISCV_PCREL_HI20 weak_function
+# RELAX: R_RISCV_RELAX *ABS*
+# RELAX: addi a1, a0, 0
+# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label5
+# RELAX: R_RISCV_RELAX *ABS*
+
+ .global global_function
+ .type global_function,@function
+global_function:
+ ret
+
+ .weak weak_function
+ .type weak_function,@function
+weak_function:
+ ret
diff --git a/llvm/test/MC/RISCV/pcrel-lo12-invalid.s b/llvm/test/MC/RISCV/pcrel-lo12-invalid.s
index 7cf2494ad8e..74a1f2fac92 100644
--- a/llvm/test/MC/RISCV/pcrel-lo12-invalid.s
+++ b/llvm/test/MC/RISCV/pcrel-lo12-invalid.s
@@ -3,3 +3,5 @@
1:
addi a0, a0, %pcrel_lo(1b) # CHECK: :[[@LINE]]:3: error: could not find corresponding %pcrel_hi
+ addi a0, a0, %pcrel_lo(0x123456) # CHECK: :[[@LINE]]:3: error: could not find corresponding %pcrel_hi
+ addi a0, a0, %pcrel_lo(foo) # CHECK: :[[@LINE]]:3: error: could not find corresponding %pcrel_hi
diff --git a/llvm/test/MC/RISCV/rv32i-aliases-valid.s b/llvm/test/MC/RISCV/rv32i-aliases-valid.s
index d2e142efcfc..5140fb2adfe 100644
--- a/llvm/test/MC/RISCV/rv32i-aliases-valid.s
+++ b/llvm/test/MC/RISCV/rv32i-aliases-valid.s
@@ -14,6 +14,8 @@
# CHECK-ALIAS....Match the alias (tests instr. to alias mapping)
# CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion)
+# Needed for testing valid %pcrel_lo expressions
+.Lpcrel_hi0: auipc a0, %pcrel_hi(foo)
# CHECK-INST: addi a0, zero, 0
# CHECK-ALIAS: mv a0, zero
@@ -71,16 +73,13 @@ li x12, 0xFFFFFFFF
# CHECK-EXPAND: addi a0, zero, 1110
li a0, %lo(0x123456)
-# CHECK-OBJ-NOALIAS: addi a0, zero, 0
-# CHECK-OBJ: R_RISCV_PCREL_LO12
-li a0, %pcrel_lo(0x123456)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_LO12
li a0, %lo(foo)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_PCREL_LO12
-li a0, %pcrel_lo(foo)
+li a0, %pcrel_lo(.Lpcrel_hi0)
.equ CONST, 0x123456
# CHECK-EXPAND: lui a0, 291
diff --git a/llvm/test/MC/RISCV/rv32i-valid.s b/llvm/test/MC/RISCV/rv32i-valid.s
index bbcfa5feac4..580f0f548c3 100644
--- a/llvm/test/MC/RISCV/rv32i-valid.s
+++ b/llvm/test/MC/RISCV/rv32i-valid.s
@@ -11,6 +11,9 @@
.equ CONST, 30
+# Needed for testing valid %pcrel_lo expressions
+.Lpcrel_hi0: auipc a0, %pcrel_hi(foo)
+
# CHECK-ASM-AND-OBJ: lui a0, 2
# CHECK-ASM: encoding: [0x37,0x25,0x00,0x00]
lui a0, 2
@@ -161,11 +164,11 @@ lw a0, 97(a2)
# CHECK-OBJ: lbu s5, 0(s6)
# CHECK-OBJ: R_RISCV_LO12
lbu s5, %lo(foo)(s6)
-# CHECK-ASM: lhu t3, %pcrel_lo(foo)(t3)
+# CHECK-ASM: lhu t3, %pcrel_lo(.Lpcrel_hi0)(t3)
# CHECK-ASM: encoding: [0x03,0x5e,0bAAAA1110,A]
# CHECK-OBJ: lhu t3, 0(t3)
# CHECK-OBJ: R_RISCV_PCREL_LO12
-lhu t3, %pcrel_lo(foo)(t3)
+lhu t3, %pcrel_lo(.Lpcrel_hi0)(t3)
# CHECK-ASM-AND-OBJ: lb t0, 30(t1)
# CHECK-ASM: encoding: [0x83,0x02,0xe3,0x01]
lb t0, CONST(t1)
diff --git a/llvm/test/MC/RISCV/rv64i-aliases-valid.s b/llvm/test/MC/RISCV/rv64i-aliases-valid.s
index 551e46f8530..9f0ad246cc9 100644
--- a/llvm/test/MC/RISCV/rv64i-aliases-valid.s
+++ b/llvm/test/MC/RISCV/rv64i-aliases-valid.s
@@ -17,6 +17,9 @@
# TODO ld
# TODO sd
+# Needed for testing valid %pcrel_lo expressions
+.Lpcrel_hi0: auipc a0, %pcrel_hi(foo)
+
# CHECK-INST: addi a0, zero, 0
# CHECK-ALIAS: mv a0, zero
li x10, 0
@@ -107,16 +110,13 @@ li t5, 0xFFFFFFFFFFFFFFFF
# CHECK-EXPAND: addi a0, zero, 1110
li a0, %lo(0x123456)
-# CHECK-OBJ-NOALIAS: addi a0, zero, 0
-# CHECK-OBJ: R_RISCV_PCREL_LO12
-li a0, %pcrel_lo(0x123456)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_LO12
li a0, %lo(foo)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_PCREL_LO12
-li a0, %pcrel_lo(foo)
+li a0, %pcrel_lo(.Lpcrel_hi0)
.equ CONST, 0x123456
# CHECK-EXPAND: lui a0, 291
OpenPOWER on IntegriCloud