Since the `RISCVExpandPseudo` pass has been split from `RISCVExpandAtomicPseudo` pass, it would be nice to run the former as early as possible (The latter has to be run as late as possible to ensure correctness). Running earlier means we can reschedule these pairs as we see fit. Running earlier in the machine pass pipeline is good, but would mean teaching many more passes about `hasLabelMustBeEmitted`. Splitting the basic blocks also pessimises possible optimisations because some optimisations are MBB-local, and others are disabled if the block has its address taken (which is notionally what `hasLabelMustBeEmitted` means). This patch uses a new approach of setting the pre-instruction symbol on the AUIPC instruction to a temporary symbol and referencing that. This avoids splitting the basic block, but allows us to reference exactly the instruction that we need to. Notionally, this approach seems more correct because we do actually want to address a specific instruction. This then allows the pass to be moved much earlier in the pass pipeline, before both scheduling and register allocation. However, to do so we must leave the MIR in SSA form (by not redefining registers), and so use a virtual register for the intermediate value. By using this virtual register, this pass now has to come before register allocation. Reviewed By: luismarques, asb Differential Revision: https://reviews.llvm.org/D82988
82 lines
2.4 KiB
LLVM
82 lines
2.4 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -mtriple=riscv32 -relocation-model=static < %s \
|
|
; RUN: | FileCheck -check-prefix=RV32-STATIC %s
|
|
; RUN: llc -mtriple=riscv32 -relocation-model=pic < %s \
|
|
; RUN: | FileCheck -check-prefix=RV32-PIC %s
|
|
; RUN: llc -mtriple=riscv64 -relocation-model=static < %s \
|
|
; RUN: | FileCheck -check-prefix=RV64-STATIC %s
|
|
; RUN: llc -mtriple=riscv64 -relocation-model=pic < %s \
|
|
; RUN: | FileCheck -check-prefix=RV64-PIC %s
|
|
|
|
; Check basic lowering of PIC addressing.
|
|
; TODO: Check other relocation models?
|
|
|
|
@external_var = external global i32
|
|
@internal_var = internal global i32 42
|
|
|
|
|
|
; external address
|
|
|
|
define i32* @f1() nounwind {
|
|
; RV32-STATIC-LABEL: f1:
|
|
; RV32-STATIC: # %bb.0: # %entry
|
|
; RV32-STATIC-NEXT: lui a0, %hi(external_var)
|
|
; RV32-STATIC-NEXT: addi a0, a0, %lo(external_var)
|
|
; RV32-STATIC-NEXT: ret
|
|
;
|
|
; RV32-PIC-LABEL: f1:
|
|
; RV32-PIC: # %bb.0: # %entry
|
|
; RV32-PIC-NEXT: .Ltmp0:
|
|
; RV32-PIC-NEXT: auipc a0, %got_pcrel_hi(external_var)
|
|
; RV32-PIC-NEXT: lw a0, %pcrel_lo(.Ltmp0)(a0)
|
|
; RV32-PIC-NEXT: ret
|
|
;
|
|
; RV64-STATIC-LABEL: f1:
|
|
; RV64-STATIC: # %bb.0: # %entry
|
|
; RV64-STATIC-NEXT: lui a0, %hi(external_var)
|
|
; RV64-STATIC-NEXT: addi a0, a0, %lo(external_var)
|
|
; RV64-STATIC-NEXT: ret
|
|
;
|
|
; RV64-PIC-LABEL: f1:
|
|
; RV64-PIC: # %bb.0: # %entry
|
|
; RV64-PIC-NEXT: .Ltmp0:
|
|
; RV64-PIC-NEXT: auipc a0, %got_pcrel_hi(external_var)
|
|
; RV64-PIC-NEXT: ld a0, %pcrel_lo(.Ltmp0)(a0)
|
|
; RV64-PIC-NEXT: ret
|
|
entry:
|
|
ret i32* @external_var
|
|
}
|
|
|
|
|
|
; internal address
|
|
|
|
define i32* @f2() nounwind {
|
|
; RV32-STATIC-LABEL: f2:
|
|
; RV32-STATIC: # %bb.0: # %entry
|
|
; RV32-STATIC-NEXT: lui a0, %hi(internal_var)
|
|
; RV32-STATIC-NEXT: addi a0, a0, %lo(internal_var)
|
|
; RV32-STATIC-NEXT: ret
|
|
;
|
|
; RV32-PIC-LABEL: f2:
|
|
; RV32-PIC: # %bb.0: # %entry
|
|
; RV32-PIC-NEXT: .Ltmp1:
|
|
; RV32-PIC-NEXT: auipc a0, %pcrel_hi(internal_var)
|
|
; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.Ltmp1)
|
|
; RV32-PIC-NEXT: ret
|
|
;
|
|
; RV64-STATIC-LABEL: f2:
|
|
; RV64-STATIC: # %bb.0: # %entry
|
|
; RV64-STATIC-NEXT: lui a0, %hi(internal_var)
|
|
; RV64-STATIC-NEXT: addi a0, a0, %lo(internal_var)
|
|
; RV64-STATIC-NEXT: ret
|
|
;
|
|
; RV64-PIC-LABEL: f2:
|
|
; RV64-PIC: # %bb.0: # %entry
|
|
; RV64-PIC-NEXT: .Ltmp1:
|
|
; RV64-PIC-NEXT: auipc a0, %pcrel_hi(internal_var)
|
|
; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.Ltmp1)
|
|
; RV64-PIC-NEXT: ret
|
|
entry:
|
|
ret i32* @internal_var
|
|
}
|