This patches adds a 16 bit register class for use with Zhinx instructions. This makes them more similar to Zfh instructions and allows us to only spill 16 bits. I've added CodeGenOnly instructions for load/store using GPRF16 as that gave better results than insert_subreg/extract_subreg. I'm using FSGNJ for GPRF16 copy with Zhinx as that gave better results. Zhinxmin will use ADDI+subreg operations. Function arguments use this new GPRF16 register class for f16 arguments with Zhinxmin. Eliminating the need to use RISCVISD::FMV* nodes. I plan to extend this idea to Zfinx next.
478 lines
17 KiB
LLVM
478 lines
17 KiB
LLVM
; 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
|
|
}
|