llvm/llvm/test/CodeGen/RISCV/codemodel-lowering.ll

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+f,+zfh -target-abi=ilp32f -code-model=small -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV32I-SMALL,RV32F-SMALL
; RUN: llc -mtriple=riscv32 -mattr=+f,+zfh -target-abi=ilp32f -code-model=medium -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV32I-MEDIUM,RV32F-MEDIUM
; RUN: llc -mtriple=riscv64 -mattr=+f,+zfh -target-abi=lp64f -code-model=small -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV64I-SMALL,RV64F-SMALL
; RUN: llc -mtriple=riscv64 -mattr=+f,+zfh -target-abi=lp64f -code-model=medium -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV64I-MEDIUM,RV64F-MEDIUM
; RUN: llc -mtriple=riscv64 -mattr=+f,+zfh -target-abi=lp64f -code-model=large -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV64I-LARGE,RV64F-LARGE
; RUN: llc -mtriple=riscv32 -mattr=+zfinx,+zhinx -target-abi=ilp32 -code-model=small -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV32I-SMALL,RV32FINX-SMALL
; RUN: llc -mtriple=riscv32 -mattr=+zfinx,+zhinx -target-abi=ilp32 -code-model=medium -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV32I-MEDIUM,RV32FINX-MEDIUM
; RUN: llc -mtriple=riscv64 -mattr=+zfinx,+zhinx -target-abi=lp64 -code-model=small -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV64I-SMALL,RV64FINX-SMALL
; RUN: llc -mtriple=riscv64 -mattr=+zfinx,+zhinx -target-abi=lp64 -code-model=medium -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV64I-MEDIUM,RV64FINX-MEDIUM
; RUN: llc -mtriple=riscv64 -mattr=+zfinx,+zhinx -target-abi=lp64 -code-model=large -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefixes=RV64I-LARGE,RV64FINX-LARGE

; Check lowering of globals
@G = global i32 0

define i32 @lower_global(i32 %a) nounwind {
; RV32I-SMALL-LABEL: lower_global:
; RV32I-SMALL:       # %bb.0:
; RV32I-SMALL-NEXT:    lui a0, %hi(G)
; RV32I-SMALL-NEXT:    lw a0, %lo(G)(a0)
; RV32I-SMALL-NEXT:    ret
;
; RV32I-MEDIUM-LABEL: lower_global:
; RV32I-MEDIUM:       # %bb.0:
; RV32I-MEDIUM-NEXT:  .Lpcrel_hi0:
; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(G)
; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi0)(a0)
; RV32I-MEDIUM-NEXT:    ret
;
; RV64I-SMALL-LABEL: lower_global:
; RV64I-SMALL:       # %bb.0:
; RV64I-SMALL-NEXT:    lui a0, %hi(G)
; RV64I-SMALL-NEXT:    lw a0, %lo(G)(a0)
; RV64I-SMALL-NEXT:    ret
;
; RV64I-MEDIUM-LABEL: lower_global:
; RV64I-MEDIUM:       # %bb.0:
; RV64I-MEDIUM-NEXT:  .Lpcrel_hi0:
; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(G)
; RV64I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi0)(a0)
; RV64I-MEDIUM-NEXT:    ret
;
; RV64I-LARGE-LABEL: lower_global:
; RV64I-LARGE:       # %bb.0:
; RV64I-LARGE-NEXT:  .Lpcrel_hi0:
; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI0_0)
; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
; RV64I-LARGE-NEXT:    lw a0, 0(a0)
; RV64I-LARGE-NEXT:    ret
  %1 = load volatile i32, ptr @G
  ret i32 %1
}

; Check lowering of blockaddresses

@addr = global ptr null

define void @lower_blockaddress() nounwind {
; RV32I-SMALL-LABEL: lower_blockaddress:
; RV32I-SMALL:       # %bb.0:
; RV32I-SMALL-NEXT:    lui a0, %hi(addr)
; RV32I-SMALL-NEXT:    li a1, 1
; RV32I-SMALL-NEXT:    sw a1, %lo(addr)(a0)
; RV32I-SMALL-NEXT:    ret
;
; RV32I-MEDIUM-LABEL: lower_blockaddress:
; RV32I-MEDIUM:       # %bb.0:
; RV32I-MEDIUM-NEXT:  .Lpcrel_hi1:
; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(addr)
; RV32I-MEDIUM-NEXT:    li a1, 1
; RV32I-MEDIUM-NEXT:    sw a1, %pcrel_lo(.Lpcrel_hi1)(a0)
; RV32I-MEDIUM-NEXT:    ret
;
; RV64I-SMALL-LABEL: lower_blockaddress:
; RV64I-SMALL:       # %bb.0:
; RV64I-SMALL-NEXT:    lui a0, %hi(addr)
; RV64I-SMALL-NEXT:    li a1, 1
; RV64I-SMALL-NEXT:    sd a1, %lo(addr)(a0)
; RV64I-SMALL-NEXT:    ret
;
; RV64I-MEDIUM-LABEL: lower_blockaddress:
; RV64I-MEDIUM:       # %bb.0:
; RV64I-MEDIUM-NEXT:  .Lpcrel_hi1:
; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(addr)
; RV64I-MEDIUM-NEXT:    li a1, 1
; RV64I-MEDIUM-NEXT:    sd a1, %pcrel_lo(.Lpcrel_hi1)(a0)
; RV64I-MEDIUM-NEXT:    ret
;
; RV64I-LARGE-LABEL: lower_blockaddress:
; RV64I-LARGE:       # %bb.0:
; RV64I-LARGE-NEXT:  .Lpcrel_hi1:
; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI1_0)
; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
; RV64I-LARGE-NEXT:    li a1, 1
; RV64I-LARGE-NEXT:    sd a1, 0(a0)
; RV64I-LARGE-NEXT:    ret
  store volatile ptr blockaddress(@lower_blockaddress, %block), ptr @addr
  ret void

block:
  unreachable
}

; Check lowering of blockaddress that forces a displacement to be added

define signext i32 @lower_blockaddress_displ(i32 signext %w) nounwind {
; RV32I-SMALL-LABEL: lower_blockaddress_displ:
; RV32I-SMALL:       # %bb.0: # %entry
; RV32I-SMALL-NEXT:    addi sp, sp, -16
; RV32I-SMALL-NEXT:    lui a1, %hi(.Ltmp0)
; RV32I-SMALL-NEXT:    addi a1, a1, %lo(.Ltmp0)
; RV32I-SMALL-NEXT:    li a2, 101
; RV32I-SMALL-NEXT:    sw a1, 8(sp)
; RV32I-SMALL-NEXT:    blt a0, a2, .LBB2_3
; RV32I-SMALL-NEXT:  # %bb.1: # %if.then
; RV32I-SMALL-NEXT:    lw a0, 8(sp)
; RV32I-SMALL-NEXT:    jr a0
; RV32I-SMALL-NEXT:  .Ltmp0: # Block address taken
; RV32I-SMALL-NEXT:  .LBB2_2: # %return
; RV32I-SMALL-NEXT:    li a0, 4
; RV32I-SMALL-NEXT:    addi sp, sp, 16
; RV32I-SMALL-NEXT:    ret
; RV32I-SMALL-NEXT:  .LBB2_3: # %return.clone
; RV32I-SMALL-NEXT:    li a0, 3
; RV32I-SMALL-NEXT:    addi sp, sp, 16
; RV32I-SMALL-NEXT:    ret
;
; RV32I-MEDIUM-LABEL: lower_blockaddress_displ:
; RV32I-MEDIUM:       # %bb.0: # %entry
; RV32I-MEDIUM-NEXT:    addi sp, sp, -16
; RV32I-MEDIUM-NEXT:  .Lpcrel_hi2:
; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(.Ltmp0)
; RV32I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi2)
; RV32I-MEDIUM-NEXT:    li a2, 101
; RV32I-MEDIUM-NEXT:    sw a1, 8(sp)
; RV32I-MEDIUM-NEXT:    blt a0, a2, .LBB2_3
; RV32I-MEDIUM-NEXT:  # %bb.1: # %if.then
; RV32I-MEDIUM-NEXT:    lw a0, 8(sp)
; RV32I-MEDIUM-NEXT:    jr a0
; RV32I-MEDIUM-NEXT:  .Ltmp0: # Block address taken
; RV32I-MEDIUM-NEXT:  .LBB2_2: # %return
; RV32I-MEDIUM-NEXT:    li a0, 4
; RV32I-MEDIUM-NEXT:    addi sp, sp, 16
; RV32I-MEDIUM-NEXT:    ret
; RV32I-MEDIUM-NEXT:  .LBB2_3: # %return.clone
; RV32I-MEDIUM-NEXT:    li a0, 3
; RV32I-MEDIUM-NEXT:    addi sp, sp, 16
; RV32I-MEDIUM-NEXT:    ret
;
; RV64I-SMALL-LABEL: lower_blockaddress_displ:
; RV64I-SMALL:       # %bb.0: # %entry
; RV64I-SMALL-NEXT:    addi sp, sp, -16
; RV64I-SMALL-NEXT:    lui a1, %hi(.Ltmp0)
; RV64I-SMALL-NEXT:    addi a1, a1, %lo(.Ltmp0)
; RV64I-SMALL-NEXT:    li a2, 101
; RV64I-SMALL-NEXT:    sd a1, 8(sp)
; RV64I-SMALL-NEXT:    blt a0, a2, .LBB2_3
; RV64I-SMALL-NEXT:  # %bb.1: # %if.then
; RV64I-SMALL-NEXT:    ld a0, 8(sp)
; RV64I-SMALL-NEXT:    jr a0
; RV64I-SMALL-NEXT:  .Ltmp0: # Block address taken
; RV64I-SMALL-NEXT:  .LBB2_2: # %return
; RV64I-SMALL-NEXT:    li a0, 4
; RV64I-SMALL-NEXT:    addi sp, sp, 16
; RV64I-SMALL-NEXT:    ret
; RV64I-SMALL-NEXT:  .LBB2_3: # %return.clone
; RV64I-SMALL-NEXT:    li a0, 3
; RV64I-SMALL-NEXT:    addi sp, sp, 16
; RV64I-SMALL-NEXT:    ret
;
; RV64I-MEDIUM-LABEL: lower_blockaddress_displ:
; RV64I-MEDIUM:       # %bb.0: # %entry
; RV64I-MEDIUM-NEXT:    addi sp, sp, -16
; RV64I-MEDIUM-NEXT:  .Lpcrel_hi2:
; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(.Ltmp0)
; RV64I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi2)
; RV64I-MEDIUM-NEXT:    li a2, 101
; RV64I-MEDIUM-NEXT:    sd a1, 8(sp)
; RV64I-MEDIUM-NEXT:    blt a0, a2, .LBB2_3
; RV64I-MEDIUM-NEXT:  # %bb.1: # %if.then
; RV64I-MEDIUM-NEXT:    ld a0, 8(sp)
; RV64I-MEDIUM-NEXT:    jr a0
; RV64I-MEDIUM-NEXT:  .Ltmp0: # Block address taken
; RV64I-MEDIUM-NEXT:  .LBB2_2: # %return
; RV64I-MEDIUM-NEXT:    li a0, 4
; RV64I-MEDIUM-NEXT:    addi sp, sp, 16
; RV64I-MEDIUM-NEXT:    ret
; RV64I-MEDIUM-NEXT:  .LBB2_3: # %return.clone
; RV64I-MEDIUM-NEXT:    li a0, 3
; RV64I-MEDIUM-NEXT:    addi sp, sp, 16
; RV64I-MEDIUM-NEXT:    ret
;
; RV64I-LARGE-LABEL: lower_blockaddress_displ:
; RV64I-LARGE:       # %bb.0: # %entry
; RV64I-LARGE-NEXT:    addi sp, sp, -16
; RV64I-LARGE-NEXT:  .Lpcrel_hi2:
; RV64I-LARGE-NEXT:    auipc a1, %pcrel_hi(.Ltmp0)
; RV64I-LARGE-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi2)
; RV64I-LARGE-NEXT:    li a2, 101
; RV64I-LARGE-NEXT:    sd a1, 8(sp)
; RV64I-LARGE-NEXT:    blt a0, a2, .LBB2_3
; RV64I-LARGE-NEXT:  # %bb.1: # %if.then
; RV64I-LARGE-NEXT:    ld a0, 8(sp)
; RV64I-LARGE-NEXT:    jr a0
; RV64I-LARGE-NEXT:  .Ltmp0: # Block address taken
; RV64I-LARGE-NEXT:  .LBB2_2: # %return
; RV64I-LARGE-NEXT:    li a0, 4
; RV64I-LARGE-NEXT:    addi sp, sp, 16
; RV64I-LARGE-NEXT:    ret
; RV64I-LARGE-NEXT:  .LBB2_3: # %return.clone
; RV64I-LARGE-NEXT:    li a0, 3
; RV64I-LARGE-NEXT:    addi sp, sp, 16
; RV64I-LARGE-NEXT:    ret
entry:
  %x = alloca ptr, align 8
  store ptr blockaddress(@lower_blockaddress_displ, %test_block), ptr %x, align 8
  %cmp = icmp sgt i32 %w, 100
  br i1 %cmp, label %if.then, label %if.end

if.then:
  %addr = load ptr, ptr %x, align 8
  br label %indirectgoto

if.end:
  br label %return

test_block:
  br label %return

return:
  %retval = phi i32 [ 3, %if.end ], [ 4, %test_block ]
  ret i32 %retval

indirectgoto:
  indirectbr ptr %addr, [ label %test_block ]
}

; Check lowering of constantpools

define float @lower_constantpool(float %a) nounwind {
; RV32F-SMALL-LABEL: lower_constantpool:
; RV32F-SMALL:       # %bb.0:
; RV32F-SMALL-NEXT:    lui a0, %hi(.LCPI3_0)
; RV32F-SMALL-NEXT:    flw fa5, %lo(.LCPI3_0)(a0)
; RV32F-SMALL-NEXT:    fadd.s fa0, fa0, fa5
; RV32F-SMALL-NEXT:    ret
;
; RV32F-MEDIUM-LABEL: lower_constantpool:
; RV32F-MEDIUM:       # %bb.0:
; RV32F-MEDIUM-NEXT:  .Lpcrel_hi3:
; RV32F-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.LCPI3_0)
; RV32F-MEDIUM-NEXT:    flw fa5, %pcrel_lo(.Lpcrel_hi3)(a0)
; RV32F-MEDIUM-NEXT:    fadd.s fa0, fa0, fa5
; RV32F-MEDIUM-NEXT:    ret
;
; RV64F-SMALL-LABEL: lower_constantpool:
; RV64F-SMALL:       # %bb.0:
; RV64F-SMALL-NEXT:    lui a0, %hi(.LCPI3_0)
; RV64F-SMALL-NEXT:    flw fa5, %lo(.LCPI3_0)(a0)
; RV64F-SMALL-NEXT:    fadd.s fa0, fa0, fa5
; RV64F-SMALL-NEXT:    ret
;
; RV64F-MEDIUM-LABEL: lower_constantpool:
; RV64F-MEDIUM:       # %bb.0:
; RV64F-MEDIUM-NEXT:  .Lpcrel_hi3:
; RV64F-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.LCPI3_0)
; RV64F-MEDIUM-NEXT:    flw fa5, %pcrel_lo(.Lpcrel_hi3)(a0)
; RV64F-MEDIUM-NEXT:    fadd.s fa0, fa0, fa5
; RV64F-MEDIUM-NEXT:    ret
;
; RV64F-LARGE-LABEL: lower_constantpool:
; RV64F-LARGE:       # %bb.0:
; RV64F-LARGE-NEXT:  .Lpcrel_hi3:
; RV64F-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI3_0)
; RV64F-LARGE-NEXT:    flw fa5, %pcrel_lo(.Lpcrel_hi3)(a0)
; RV64F-LARGE-NEXT:    fadd.s fa0, fa0, fa5
; RV64F-LARGE-NEXT:    ret
;
; RV32FINX-SMALL-LABEL: lower_constantpool:
; RV32FINX-SMALL:       # %bb.0:
; RV32FINX-SMALL-NEXT:    lui a1, 260097
; RV32FINX-SMALL-NEXT:    addi a1, a1, -2048
; RV32FINX-SMALL-NEXT:    fadd.s a0, a0, a1
; RV32FINX-SMALL-NEXT:    ret
;
; RV32FINX-MEDIUM-LABEL: lower_constantpool:
; RV32FINX-MEDIUM:       # %bb.0:
; RV32FINX-MEDIUM-NEXT:    lui a1, 260097
; RV32FINX-MEDIUM-NEXT:    addi a1, a1, -2048
; RV32FINX-MEDIUM-NEXT:    fadd.s a0, a0, a1
; RV32FINX-MEDIUM-NEXT:    ret
;
; RV64FINX-SMALL-LABEL: lower_constantpool:
; RV64FINX-SMALL:       # %bb.0:
; RV64FINX-SMALL-NEXT:    lui a1, 260097
; RV64FINX-SMALL-NEXT:    addiw a1, a1, -2048
; RV64FINX-SMALL-NEXT:    fadd.s a0, a0, a1
; RV64FINX-SMALL-NEXT:    ret
;
; RV64FINX-MEDIUM-LABEL: lower_constantpool:
; RV64FINX-MEDIUM:       # %bb.0:
; RV64FINX-MEDIUM-NEXT:    lui a1, 260097
; RV64FINX-MEDIUM-NEXT:    addiw a1, a1, -2048
; RV64FINX-MEDIUM-NEXT:    fadd.s a0, a0, a1
; RV64FINX-MEDIUM-NEXT:    ret
;
; RV64FINX-LARGE-LABEL: lower_constantpool:
; RV64FINX-LARGE:       # %bb.0:
; RV64FINX-LARGE-NEXT:    lui a1, 260097
; RV64FINX-LARGE-NEXT:    addiw a1, a1, -2048
; RV64FINX-LARGE-NEXT:    fadd.s a0, a0, a1
; RV64FINX-LARGE-NEXT:    ret
  %1 = fadd float %a, 1.000244140625
  ret float %1
}

; Check lowering of extern_weaks
@W = extern_weak global i32

define i32 @lower_extern_weak(i32 %a) nounwind {
; RV32I-SMALL-LABEL: lower_extern_weak:
; RV32I-SMALL:       # %bb.0:
; RV32I-SMALL-NEXT:    lui a0, %hi(W)
; RV32I-SMALL-NEXT:    lw a0, %lo(W)(a0)
; RV32I-SMALL-NEXT:    ret
;
; RV32F-MEDIUM-LABEL: lower_extern_weak:
; RV32F-MEDIUM:       # %bb.0:
; RV32F-MEDIUM-NEXT:  .Lpcrel_hi4:
; RV32F-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(W)
; RV32F-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi4)(a0)
; RV32F-MEDIUM-NEXT:    lw a0, 0(a0)
; RV32F-MEDIUM-NEXT:    ret
;
; RV64I-SMALL-LABEL: lower_extern_weak:
; RV64I-SMALL:       # %bb.0:
; RV64I-SMALL-NEXT:    lui a0, %hi(W)
; RV64I-SMALL-NEXT:    lw a0, %lo(W)(a0)
; RV64I-SMALL-NEXT:    ret
;
; RV64F-MEDIUM-LABEL: lower_extern_weak:
; RV64F-MEDIUM:       # %bb.0:
; RV64F-MEDIUM-NEXT:  .Lpcrel_hi4:
; RV64F-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(W)
; RV64F-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
; RV64F-MEDIUM-NEXT:    lw a0, 0(a0)
; RV64F-MEDIUM-NEXT:    ret
;
; RV64F-LARGE-LABEL: lower_extern_weak:
; RV64F-LARGE:       # %bb.0:
; RV64F-LARGE-NEXT:  .Lpcrel_hi4:
; RV64F-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI4_0)
; RV64F-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
; RV64F-LARGE-NEXT:    lw a0, 0(a0)
; RV64F-LARGE-NEXT:    ret
;
; RV32FINX-MEDIUM-LABEL: lower_extern_weak:
; RV32FINX-MEDIUM:       # %bb.0:
; RV32FINX-MEDIUM-NEXT:  .Lpcrel_hi3:
; RV32FINX-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(W)
; RV32FINX-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi3)(a0)
; RV32FINX-MEDIUM-NEXT:    lw a0, 0(a0)
; RV32FINX-MEDIUM-NEXT:    ret
;
; RV64FINX-MEDIUM-LABEL: lower_extern_weak:
; RV64FINX-MEDIUM:       # %bb.0:
; RV64FINX-MEDIUM-NEXT:  .Lpcrel_hi3:
; RV64FINX-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(W)
; RV64FINX-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi3)(a0)
; RV64FINX-MEDIUM-NEXT:    lw a0, 0(a0)
; RV64FINX-MEDIUM-NEXT:    ret
;
; RV64FINX-LARGE-LABEL: lower_extern_weak:
; RV64FINX-LARGE:       # %bb.0:
; RV64FINX-LARGE-NEXT:  .Lpcrel_hi3:
; RV64FINX-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI4_0)
; RV64FINX-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi3)(a0)
; RV64FINX-LARGE-NEXT:    lw a0, 0(a0)
; RV64FINX-LARGE-NEXT:    ret
  %1 = load volatile i32, ptr @W
  ret i32 %1
}

@X = global half 1.5

define half @lower_global_half(half %a) nounwind {
; RV32F-SMALL-LABEL: lower_global_half:
; RV32F-SMALL:       # %bb.0:
; RV32F-SMALL-NEXT:    lui a0, %hi(X)
; RV32F-SMALL-NEXT:    flh fa5, %lo(X)(a0)
; RV32F-SMALL-NEXT:    fadd.h fa0, fa0, fa5
; RV32F-SMALL-NEXT:    ret
;
; RV32F-MEDIUM-LABEL: lower_global_half:
; RV32F-MEDIUM:       # %bb.0:
; RV32F-MEDIUM-NEXT:  .Lpcrel_hi5:
; RV32F-MEDIUM-NEXT:    auipc a0, %pcrel_hi(X)
; RV32F-MEDIUM-NEXT:    flh fa5, %pcrel_lo(.Lpcrel_hi5)(a0)
; RV32F-MEDIUM-NEXT:    fadd.h fa0, fa0, fa5
; RV32F-MEDIUM-NEXT:    ret
;
; RV64F-SMALL-LABEL: lower_global_half:
; RV64F-SMALL:       # %bb.0:
; RV64F-SMALL-NEXT:    lui a0, %hi(X)
; RV64F-SMALL-NEXT:    flh fa5, %lo(X)(a0)
; RV64F-SMALL-NEXT:    fadd.h fa0, fa0, fa5
; RV64F-SMALL-NEXT:    ret
;
; RV64F-MEDIUM-LABEL: lower_global_half:
; RV64F-MEDIUM:       # %bb.0:
; RV64F-MEDIUM-NEXT:  .Lpcrel_hi5:
; RV64F-MEDIUM-NEXT:    auipc a0, %pcrel_hi(X)
; RV64F-MEDIUM-NEXT:    flh fa5, %pcrel_lo(.Lpcrel_hi5)(a0)
; RV64F-MEDIUM-NEXT:    fadd.h fa0, fa0, fa5
; RV64F-MEDIUM-NEXT:    ret
;
; RV64F-LARGE-LABEL: lower_global_half:
; RV64F-LARGE:       # %bb.0:
; RV64F-LARGE-NEXT:  .Lpcrel_hi5:
; RV64F-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI5_0)
; RV64F-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi5)(a0)
; RV64F-LARGE-NEXT:    flh fa5, 0(a0)
; RV64F-LARGE-NEXT:    fadd.h fa0, fa0, fa5
; RV64F-LARGE-NEXT:    ret
;
; RV32FINX-SMALL-LABEL: lower_global_half:
; RV32FINX-SMALL:       # %bb.0:
; RV32FINX-SMALL-NEXT:    lui a1, %hi(X)
; RV32FINX-SMALL-NEXT:    lh a1, %lo(X)(a1)
; RV32FINX-SMALL-NEXT:    fadd.h a0, a0, a1
; RV32FINX-SMALL-NEXT:    ret
;
; RV32FINX-MEDIUM-LABEL: lower_global_half:
; RV32FINX-MEDIUM:       # %bb.0:
; RV32FINX-MEDIUM-NEXT:  .Lpcrel_hi4:
; RV32FINX-MEDIUM-NEXT:    auipc a1, %pcrel_hi(X)
; RV32FINX-MEDIUM-NEXT:    lh a1, %pcrel_lo(.Lpcrel_hi4)(a1)
; RV32FINX-MEDIUM-NEXT:    fadd.h a0, a0, a1
; RV32FINX-MEDIUM-NEXT:    ret
;
; RV64FINX-SMALL-LABEL: lower_global_half:
; RV64FINX-SMALL:       # %bb.0:
; RV64FINX-SMALL-NEXT:    lui a1, %hi(X)
; RV64FINX-SMALL-NEXT:    lh a1, %lo(X)(a1)
; RV64FINX-SMALL-NEXT:    fadd.h a0, a0, a1
; RV64FINX-SMALL-NEXT:    ret
;
; RV64FINX-MEDIUM-LABEL: lower_global_half:
; RV64FINX-MEDIUM:       # %bb.0:
; RV64FINX-MEDIUM-NEXT:  .Lpcrel_hi4:
; RV64FINX-MEDIUM-NEXT:    auipc a1, %pcrel_hi(X)
; RV64FINX-MEDIUM-NEXT:    lh a1, %pcrel_lo(.Lpcrel_hi4)(a1)
; RV64FINX-MEDIUM-NEXT:    fadd.h a0, a0, a1
; RV64FINX-MEDIUM-NEXT:    ret
;
; RV64FINX-LARGE-LABEL: lower_global_half:
; RV64FINX-LARGE:       # %bb.0:
; RV64FINX-LARGE-NEXT:  .Lpcrel_hi4:
; RV64FINX-LARGE-NEXT:    auipc a1, %pcrel_hi(.LCPI5_0)
; RV64FINX-LARGE-NEXT:    ld a1, %pcrel_lo(.Lpcrel_hi4)(a1)
; RV64FINX-LARGE-NEXT:    lh a1, 0(a1)
; RV64FINX-LARGE-NEXT:    fadd.h a0, a0, a1
; RV64FINX-LARGE-NEXT:    ret
  %b = load half, ptr @X
  %1 = fadd half %a, %b
  ret half %1
}