# REQUIRES: aarch64 # RUN: rm -rf %t && split-file %s %t # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/a.s -o %t/a.o # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/unpaired.s -o %t/unpaired.o # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/lone-ldr.s -o %t/lone-ldr.o # RUN: ld.lld %t/a.o -T %t/out-of-adr-range.t -o %t/a # RUN: llvm-objdump --no-show-raw-insn -d %t/a | FileCheck %s ## Symbol 'x' is nonpreemptible, the relaxation should be applied. ## This test verifies the encoding when the register x1 is used. # CHECK: adrp x1 # CHECK-NEXT: add x1, x1 ## ADRP contains a nonzero addend, no relaxations should be applied. # CHECK-NEXT: adrp x2 # CHECK-NEXT: ldr ## LDR contains a nonzero addend, no relaxations should be applied. # CHECK-NEXT: adrp x3 # CHECK-NEXT: ldr ## LDR and ADRP use different registers, no relaxations should be applied. # CHECK-NEXT: adrp x4 # CHECK-NEXT: ldr ## LDR and ADRP use different registers, no relaxations should be applied. # CHECK-NEXT: adrp x6 # CHECK-NEXT: ldr # RUN: ld.lld %t/a.o -T %t/within-adr-range.t -o %t/a # RUN: llvm-objdump --no-show-raw-insn -d %t/a | FileCheck --check-prefix=ADR %s ## Symbol 'x' is nonpreemptible, the relaxation should be applied. # ADR: nop # ADR-NEXT: adr x1 ## Symbol 'x' is nonpreemptible, but --no-relax surpresses relaxations. # RUN: ld.lld %t/a.o -T %t/out-of-adr-range.t --no-relax -o %t/no-relax # RUN: llvm-objdump --no-show-raw-insn -d %t/no-relax | \ # RUN: FileCheck --check-prefix=X1-NO-RELAX %s # X1-NO-RELAX: adrp x1 # X1-NO-RELAX-NEXT: ldr ## Symbol 'x' is nonpreemptible, but the address is not within adrp range. # RUN: ld.lld %t/a.o -T %t/out-of-range.t -o %t/out-of-range # RUN: llvm-objdump --no-show-raw-insn -d %t/out-of-range | \ # RUN: FileCheck --check-prefix=X1-NO-RELAX %s ## Relocations do not appear in pairs, no relaxations should be applied. # RUN: ld.lld %t/unpaired.o -o %t/unpaired # RUN: llvm-objdump --no-show-raw-insn -d %t/unpaired | \ # RUN: FileCheck --check-prefix=UNPAIRED %s # UNPAIRED: adrp x0 # UNPAIRED-NEXT: b # UNPAIRED-NEXT: adrp x0 # UNPAIRED: ldr x0 ## Relocations do not appear in pairs, no relaxations should be applied. # RUN: ld.lld %t/lone-ldr.o -o %t/lone-ldr # RUN: llvm-objdump --no-show-raw-insn -d %t/lone-ldr | \ # RUN: FileCheck --check-prefix=LONE-LDR %s # LONE-LDR: ldr x0 ## This linker script ensures that .rodata and .text are sufficiently (>1M) ## far apart so that the adrp + ldr pair cannot be relaxed to adr + nop. #--- out-of-adr-range.t SECTIONS { .rodata 0x1000: { *(.rodata) } .text 0x200100: { *(.text) } } ## This linker script ensures that .rodata and .text are sufficiently (<1M) ## close to each other so that the adrp + ldr pair can be relaxed to nop + adr. #--- within-adr-range.t SECTIONS { .rodata 0x1000: { *(.rodata) } .text 0x2000: { *(.text) } } ## This linker script ensures that .rodata and .text are sufficiently (>4GB) ## far apart so that the adrp + ldr pair cannot be relaxed. #--- out-of-range.t SECTIONS { .rodata 0x1000: { *(.rodata) } .text 0x100002000: { *(.text) } } #--- a.s .rodata .hidden x x: .word 10 .text .global _start _start: adrp x1, :got:x ldr x1, [x1, #:got_lo12:x] adrp x2, :got:x+1 ldr x2, [x2, #:got_lo12:x] adrp x3, :got:x ldr x3, [x3, #:got_lo12:x+8] adrp x4, :got:x ldr x5, [x4, #:got_lo12:x] adrp x6, :got:x ldr x6, [x0, #:got_lo12:x] #--- unpaired.s .text .hidden x x: nop .global _start _start: adrp x0, :got:x b L adrp x0, :got:x L: ldr x0, [x0, #:got_lo12:x] #--- lone-ldr.s .text .hidden x x: nop .global _start _start: ldr x0, [x0, #:got_lo12:x]