This improves our coverage of soft float libcalls lowering. Remove most of the test cases from rv64i-single-softfloat.ll. They were duplicated in the test files that now test softflow. Only a couple test cases for constrained FP remain. Those should be removed when we start supporting constrained FP. This is follow up from D113528.
2153 lines
73 KiB
LLVM
2153 lines
73 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfh -verify-machineinstrs \
|
|
; RUN: -target-abi ilp32f < %s | FileCheck -check-prefix=RV32IZFH %s
|
|
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zfh -verify-machineinstrs \
|
|
; RUN: -target-abi lp64f < %s | FileCheck -check-prefix=RV64IZFH %s
|
|
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
|
|
; RUN: | FileCheck -check-prefix=RV32I %s
|
|
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
|
|
; RUN: | FileCheck -check-prefix=RV64I %s
|
|
|
|
; These tests are each targeted at a particular RISC-V FPU instruction. Most
|
|
; other files in this folder exercise LLVM IR instructions that don't directly
|
|
; match a RISC-V instruction.
|
|
|
|
define half @fadd_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fadd_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fadd.h fa0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fadd_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fadd.h fa0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fadd_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fadd_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = fadd half %a, %b
|
|
ret half %1
|
|
}
|
|
|
|
define half @fsub_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fsub_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fsub.h fa0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fsub_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fsub.h fa0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fsub_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __subsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fsub_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __subsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = fsub half %a, %b
|
|
ret half %1
|
|
}
|
|
|
|
define half @fmul_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fmul_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmul.h fa0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fmul_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmul.h fa0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fmul_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __mulsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fmul_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __mulsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = fmul half %a, %b
|
|
ret half %1
|
|
}
|
|
|
|
define half @fdiv_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fdiv_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fdiv.h fa0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fdiv_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fdiv.h fa0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fdiv_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __divsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fdiv_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __divsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = fdiv half %a, %b
|
|
ret half %1
|
|
}
|
|
|
|
declare half @llvm.sqrt.f16(half)
|
|
|
|
define half @fsqrt_s(half %a) nounwind {
|
|
; RV32IZFH-LABEL: fsqrt_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fsqrt.h fa0, fa0
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fsqrt_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fsqrt.h fa0, fa0
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fsqrt_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi a1, a1, -1
|
|
; RV32I-NEXT: and a0, a0, a1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: call sqrtf@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fsqrt_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw a1, a1, -1
|
|
; RV64I-NEXT: and a0, a0, a1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: call sqrtf@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = call half @llvm.sqrt.f16(half %a)
|
|
ret half %1
|
|
}
|
|
|
|
declare half @llvm.copysign.f16(half, half)
|
|
|
|
define half @fsgnj_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fsgnj_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fsgnj.h fa0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fsgnj_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fsgnj.h fa0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fsgnj_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: lui a2, 1048568
|
|
; RV32I-NEXT: and a1, a1, a2
|
|
; RV32I-NEXT: lui a2, 8
|
|
; RV32I-NEXT: addi a2, a2, -1
|
|
; RV32I-NEXT: and a0, a0, a2
|
|
; RV32I-NEXT: or a0, a0, a1
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fsgnj_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: lui a2, 1048568
|
|
; RV64I-NEXT: and a1, a1, a2
|
|
; RV64I-NEXT: lui a2, 8
|
|
; RV64I-NEXT: addiw a2, a2, -1
|
|
; RV64I-NEXT: and a0, a0, a2
|
|
; RV64I-NEXT: or a0, a0, a1
|
|
; RV64I-NEXT: ret
|
|
%1 = call half @llvm.copysign.f16(half %a, half %b)
|
|
ret half %1
|
|
}
|
|
|
|
; This function performs extra work to ensure that
|
|
; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
|
|
define i32 @fneg_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fneg_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa0, fa0
|
|
; RV32IZFH-NEXT: fneg.h ft1, ft0
|
|
; RV32IZFH-NEXT: feq.h a0, ft0, ft1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fneg_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa0, fa0
|
|
; RV64IZFH-NEXT: fneg.h ft1, ft0
|
|
; RV64IZFH-NEXT: feq.h a0, ft0, ft1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fneg_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s1, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: lui a0, 524288
|
|
; RV32I-NEXT: xor a0, s0, a0
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s0
|
|
; RV32I-NEXT: call __eqsf2@plt
|
|
; RV32I-NEXT: seqz a0, a0
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fneg_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s1, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: lui a0, 524288
|
|
; RV64I-NEXT: xor a0, s0, a0
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s0
|
|
; RV64I-NEXT: call __eqsf2@plt
|
|
; RV64I-NEXT: seqz a0, a0
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = fadd half %a, %a
|
|
%2 = fneg half %1
|
|
%3 = fcmp oeq half %1, %2
|
|
%4 = zext i1 %3 to i32
|
|
ret i32 %4
|
|
}
|
|
|
|
; This function performs extra work to ensure that
|
|
; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
|
|
define half @fsgnjn_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fsgnjn_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa0, fa1
|
|
; RV32IZFH-NEXT: fsgnjn.h fa0, fa0, ft0
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fsgnjn_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa0, fa1
|
|
; RV64IZFH-NEXT: fsgnjn.h fa0, fa0, ft0
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fsgnjn_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s3, a1
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: lui a0, 16
|
|
; RV32I-NEXT: addi s0, a0, -1
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s3, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: lui a1, 524288
|
|
; RV32I-NEXT: xor a0, a0, a1
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lui a1, 1048568
|
|
; RV32I-NEXT: and a0, a0, a1
|
|
; RV32I-NEXT: lui a1, 8
|
|
; RV32I-NEXT: addi a1, a1, -1
|
|
; RV32I-NEXT: and a1, s2, a1
|
|
; RV32I-NEXT: or a0, a1, a0
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fsgnjn_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s3, a1
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: lui a0, 16
|
|
; RV64I-NEXT: addiw s0, a0, -1
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s3, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: lui a1, 524288
|
|
; RV64I-NEXT: xor a0, a0, a1
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: lui a1, 1048568
|
|
; RV64I-NEXT: and a0, a0, a1
|
|
; RV64I-NEXT: lui a1, 8
|
|
; RV64I-NEXT: addiw a1, a1, -1
|
|
; RV64I-NEXT: and a1, s2, a1
|
|
; RV64I-NEXT: or a0, a1, a0
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%1 = fadd half %a, %b
|
|
%2 = fneg half %1
|
|
%3 = call half @llvm.copysign.f16(half %a, half %2)
|
|
ret half %3
|
|
}
|
|
|
|
declare half @llvm.fabs.f16(half)
|
|
|
|
; This function performs extra work to ensure that
|
|
; DAGCombiner::visitBITCAST doesn't replace the fabs with an and.
|
|
define half @fabs_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fabs_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa0, fa1
|
|
; RV32IZFH-NEXT: fabs.h ft1, ft0
|
|
; RV32IZFH-NEXT: fadd.h fa0, ft1, ft0
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fabs_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa0, fa1
|
|
; RV64IZFH-NEXT: fabs.h ft1, ft0
|
|
; RV64IZFH-NEXT: fadd.h fa0, ft1, ft0
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fabs_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s1, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: and a0, s2, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s0
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: lui a0, 524288
|
|
; RV32I-NEXT: addi a0, a0, -1
|
|
; RV32I-NEXT: and a0, s0, a0
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, s0
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fabs_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s1, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: and a0, s2, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s0
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: lui a0, 524288
|
|
; RV64I-NEXT: addiw a0, a0, -1
|
|
; RV64I-NEXT: and a0, s0, a0
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, s0
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = fadd half %a, %b
|
|
%2 = call half @llvm.fabs.f16(half %1)
|
|
%3 = fadd half %2, %1
|
|
ret half %3
|
|
}
|
|
|
|
declare half @llvm.minnum.f16(half, half)
|
|
|
|
define half @fmin_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fmin_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmin.h fa0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fmin_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmin.h fa0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fmin_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call fminf@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fmin_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call fminf@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = call half @llvm.minnum.f16(half %a, half %b)
|
|
ret half %1
|
|
}
|
|
|
|
declare half @llvm.maxnum.f16(half, half)
|
|
|
|
define half @fmax_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fmax_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmax.h fa0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fmax_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmax.h fa0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fmax_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call fmaxf@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fmax_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call fmaxf@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = call half @llvm.maxnum.f16(half %a, half %b)
|
|
ret half %1
|
|
}
|
|
|
|
define i32 @feq_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: feq_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: feq.h a0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: feq_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: feq.h a0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: feq_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __eqsf2@plt
|
|
; RV32I-NEXT: seqz a0, a0
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: feq_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __eqsf2@plt
|
|
; RV64I-NEXT: seqz a0, a0
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = fcmp oeq half %a, %b
|
|
%2 = zext i1 %1 to i32
|
|
ret i32 %2
|
|
}
|
|
|
|
define i32 @flt_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: flt_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: flt.h a0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: flt_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: flt.h a0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: flt_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __ltsf2@plt
|
|
; RV32I-NEXT: slti a0, a0, 0
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: flt_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __ltsf2@plt
|
|
; RV64I-NEXT: slti a0, a0, 0
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = fcmp olt half %a, %b
|
|
%2 = zext i1 %1 to i32
|
|
ret i32 %2
|
|
}
|
|
|
|
define i32 @fle_s(half %a, half %b) nounwind {
|
|
; RV32IZFH-LABEL: fle_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fle.h a0, fa0, fa1
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fle_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fle.h a0, fa0, fa1
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fle_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __lesf2@plt
|
|
; RV32I-NEXT: slti a0, a0, 1
|
|
; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fle_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -32
|
|
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __lesf2@plt
|
|
; RV64I-NEXT: slti a0, a0, 1
|
|
; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 32
|
|
; RV64I-NEXT: ret
|
|
%1 = fcmp ole half %a, %b
|
|
%2 = zext i1 %1 to i32
|
|
ret i32 %2
|
|
}
|
|
|
|
declare half @llvm.fma.f16(half, half, half)
|
|
|
|
define half @fmadd_s(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fmadd_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fmadd_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fmadd_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a2
|
|
; RV32I-NEXT: mv s1, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: and a0, s1, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a2, a0
|
|
; RV32I-NEXT: mv a0, s3
|
|
; RV32I-NEXT: mv a1, s1
|
|
; RV32I-NEXT: call fmaf@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fmadd_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a2
|
|
; RV64I-NEXT: mv s1, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: and a0, s1, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a2, a0
|
|
; RV64I-NEXT: mv a0, s3
|
|
; RV64I-NEXT: mv a1, s1
|
|
; RV64I-NEXT: call fmaf@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%1 = call half @llvm.fma.f16(half %a, half %b, half %c)
|
|
ret half %1
|
|
}
|
|
|
|
define half @fmsub_s(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fmsub_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV32IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fmsub_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV64IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fmsub_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: lui a0, 16
|
|
; RV32I-NEXT: addi s0, a0, -1
|
|
; RV32I-NEXT: and a0, a2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: lui a1, 524288
|
|
; RV32I-NEXT: xor a0, a0, a1
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: and a0, s1, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s4, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a2, a0
|
|
; RV32I-NEXT: mv a0, s3
|
|
; RV32I-NEXT: mv a1, s1
|
|
; RV32I-NEXT: call fmaf@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fmsub_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s4, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: lui a0, 16
|
|
; RV64I-NEXT: addiw s0, a0, -1
|
|
; RV64I-NEXT: and a0, a2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: lui a1, 524288
|
|
; RV64I-NEXT: xor a0, a0, a1
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: and a0, s1, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s4, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a2, a0
|
|
; RV64I-NEXT: mv a0, s3
|
|
; RV64I-NEXT: mv a1, s1
|
|
; RV64I-NEXT: call fmaf@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s4, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%c_ = fadd half 0.0, %c ; avoid negation using xor
|
|
%negc = fsub half -0.0, %c_
|
|
%1 = call half @llvm.fma.f16(half %a, half %b, half %negc)
|
|
ret half %1
|
|
}
|
|
|
|
define half @fnmadd_s(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fnmadd_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV32IZFH-NEXT: fadd.h ft1, fa0, ft0
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV32IZFH-NEXT: fnmadd.h fa0, ft1, fa1, ft0
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fnmadd_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV64IZFH-NEXT: fadd.h ft1, fa0, ft0
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV64IZFH-NEXT: fnmadd.h fa0, ft1, fa1, ft0
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fnmadd_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s3, a2
|
|
; RV32I-NEXT: mv s2, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s1, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: and a0, s3, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: and a0, s4, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: lui s4, 524288
|
|
; RV32I-NEXT: xor a0, a0, s4
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: and a0, s0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: xor a0, a0, s4
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: and a0, s2, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: and a0, s3, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: and a0, s4, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a2, a0
|
|
; RV32I-NEXT: mv a0, s0
|
|
; RV32I-NEXT: mv a1, s2
|
|
; RV32I-NEXT: call fmaf@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fnmadd_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s4, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s3, a2
|
|
; RV64I-NEXT: mv s2, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s1, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: and a0, s3, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: and a0, s4, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: lui s4, 524288
|
|
; RV64I-NEXT: xor a0, a0, s4
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: and a0, s0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: xor a0, a0, s4
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: and a0, s2, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: and a0, s3, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: and a0, s4, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a2, a0
|
|
; RV64I-NEXT: mv a0, s0
|
|
; RV64I-NEXT: mv a1, s2
|
|
; RV64I-NEXT: call fmaf@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s4, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%a_ = fadd half 0.0, %a
|
|
%c_ = fadd half 0.0, %c
|
|
%nega = fsub half -0.0, %a_
|
|
%negc = fsub half -0.0, %c_
|
|
%1 = call half @llvm.fma.f16(half %nega, half %b, half %negc)
|
|
ret half %1
|
|
}
|
|
|
|
define half @fnmadd_s_2(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fnmadd_s_2:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV32IZFH-NEXT: fadd.h ft1, fa1, ft0
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV32IZFH-NEXT: fnmadd.h fa0, ft1, fa0, ft0
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fnmadd_s_2:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV64IZFH-NEXT: fadd.h ft1, fa1, ft0
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV64IZFH-NEXT: fnmadd.h fa0, ft1, fa0, ft0
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fnmadd_s_2:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s3, a2
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: lui a0, 16
|
|
; RV32I-NEXT: addi s1, a0, -1
|
|
; RV32I-NEXT: and a0, a1, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: and a0, s3, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: and a0, s4, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: lui s4, 524288
|
|
; RV32I-NEXT: xor a0, a0, s4
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: and a0, s0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: xor a0, a0, s4
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: and a0, s2, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: and a0, s3, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: and a0, s4, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a2, a0
|
|
; RV32I-NEXT: mv a0, s2
|
|
; RV32I-NEXT: mv a1, s0
|
|
; RV32I-NEXT: call fmaf@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fnmadd_s_2:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s4, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s3, a2
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: lui a0, 16
|
|
; RV64I-NEXT: addiw s1, a0, -1
|
|
; RV64I-NEXT: and a0, a1, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: and a0, s3, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: and a0, s4, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: lui s4, 524288
|
|
; RV64I-NEXT: xor a0, a0, s4
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: and a0, s0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: xor a0, a0, s4
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: and a0, s2, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: and a0, s3, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: and a0, s4, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a2, a0
|
|
; RV64I-NEXT: mv a0, s2
|
|
; RV64I-NEXT: mv a1, s0
|
|
; RV64I-NEXT: call fmaf@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s4, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%b_ = fadd half 0.0, %b
|
|
%c_ = fadd half 0.0, %c
|
|
%negb = fsub half -0.0, %b_
|
|
%negc = fsub half -0.0, %c_
|
|
%1 = call half @llvm.fma.f16(half %a, half %negb, half %negc)
|
|
ret half %1
|
|
}
|
|
|
|
define half @fnmsub_s(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fnmsub_s:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa0, ft0
|
|
; RV32IZFH-NEXT: fnmsub.h fa0, ft0, fa1, fa2
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fnmsub_s:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa0, ft0
|
|
; RV64IZFH-NEXT: fnmsub.h fa0, ft0, fa1, fa2
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fnmsub_s:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a2
|
|
; RV32I-NEXT: mv s1, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: lui a1, 524288
|
|
; RV32I-NEXT: xor a0, a0, a1
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: and a0, s1, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s4, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, s3
|
|
; RV32I-NEXT: mv a2, s1
|
|
; RV32I-NEXT: call fmaf@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fnmsub_s:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s4, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a2
|
|
; RV64I-NEXT: mv s1, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: lui a1, 524288
|
|
; RV64I-NEXT: xor a0, a0, a1
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: and a0, s1, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s4, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, s3
|
|
; RV64I-NEXT: mv a2, s1
|
|
; RV64I-NEXT: call fmaf@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s4, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%a_ = fadd half 0.0, %a
|
|
%nega = fsub half -0.0, %a_
|
|
%1 = call half @llvm.fma.f16(half %nega, half %b, half %c)
|
|
ret half %1
|
|
}
|
|
|
|
define half @fnmsub_s_2(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fnmsub_s_2:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa1, ft0
|
|
; RV32IZFH-NEXT: fnmsub.h fa0, ft0, fa0, fa2
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fnmsub_s_2:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa1, ft0
|
|
; RV64IZFH-NEXT: fnmsub.h fa0, ft0, fa0, fa2
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fnmsub_s_2:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a2
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: lui a0, 16
|
|
; RV32I-NEXT: addi s0, a0, -1
|
|
; RV32I-NEXT: and a0, a1, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: lui a1, 524288
|
|
; RV32I-NEXT: xor a0, a0, a1
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: and a0, s1, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s4, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s3
|
|
; RV32I-NEXT: mv a2, s1
|
|
; RV32I-NEXT: call fmaf@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fnmsub_s_2:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s4, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a2
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: lui a0, 16
|
|
; RV64I-NEXT: addiw s0, a0, -1
|
|
; RV64I-NEXT: and a0, a1, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: lui a1, 524288
|
|
; RV64I-NEXT: xor a0, a0, a1
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: and a0, s1, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s4, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s3
|
|
; RV64I-NEXT: mv a2, s1
|
|
; RV64I-NEXT: call fmaf@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s4, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%b_ = fadd half 0.0, %b
|
|
%negb = fsub half -0.0, %b_
|
|
%1 = call half @llvm.fma.f16(half %a, half %negb, half %c)
|
|
ret half %1
|
|
}
|
|
|
|
define half @fmadd_s_contract(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fmadd_s_contract:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fmadd_s_contract:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fmadd_s_contract:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a2
|
|
; RV32I-NEXT: mv s3, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s1, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: and a0, s3, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s0
|
|
; RV32I-NEXT: call __mulsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: and a0, s2, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: and a0, s0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, s2
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fmadd_s_contract:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a2
|
|
; RV64I-NEXT: mv s3, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s1, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: and a0, s3, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s0
|
|
; RV64I-NEXT: call __mulsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: and a0, s2, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: and a0, s0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, s2
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%1 = fmul contract half %a, %b
|
|
%2 = fadd contract half %1, %c
|
|
ret half %2
|
|
}
|
|
|
|
define half @fmsub_s_contract(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fmsub_s_contract:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV32IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fmsub_s_contract:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV64IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fmsub_s_contract:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s3, a1
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: lui a0, 16
|
|
; RV32I-NEXT: addi s0, a0, -1
|
|
; RV32I-NEXT: and a0, a2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: and a0, s1, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s3, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __mulsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s1
|
|
; RV32I-NEXT: call __subsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fmsub_s_contract:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s3, a1
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: lui a0, 16
|
|
; RV64I-NEXT: addiw s0, a0, -1
|
|
; RV64I-NEXT: and a0, a2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: and a0, s1, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s3, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __mulsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s1
|
|
; RV64I-NEXT: call __subsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%c_ = fadd half 0.0, %c ; avoid negation using xor
|
|
%1 = fmul contract half %a, %b
|
|
%2 = fsub contract half %1, %c_
|
|
ret half %2
|
|
}
|
|
|
|
define half @fnmadd_s_contract(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fnmadd_s_contract:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV32IZFH-NEXT: fadd.h ft1, fa0, ft0
|
|
; RV32IZFH-NEXT: fadd.h ft2, fa1, ft0
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV32IZFH-NEXT: fnmadd.h fa0, ft1, ft2, ft0
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fnmadd_s_contract:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV64IZFH-NEXT: fadd.h ft1, fa0, ft0
|
|
; RV64IZFH-NEXT: fadd.h ft2, fa1, ft0
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0
|
|
; RV64IZFH-NEXT: fnmadd.h fa0, ft1, ft2, ft0
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fnmadd_s_contract:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a2
|
|
; RV32I-NEXT: mv s0, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s1, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: and a0, s0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: and a0, s2, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: and a0, s3, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: and a0, s4, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s0
|
|
; RV32I-NEXT: call __mulsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: and a0, a0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: lui a1, 524288
|
|
; RV32I-NEXT: xor a0, a0, a1
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: and a0, s2, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: and a0, s0, s1
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, s2
|
|
; RV32I-NEXT: call __subsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fnmadd_s_contract:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s4, 0(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a2
|
|
; RV64I-NEXT: mv s0, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s1, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: and a0, s0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: and a0, s2, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: and a0, s3, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: and a0, s4, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s0
|
|
; RV64I-NEXT: call __mulsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: and a0, a0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: lui a1, 524288
|
|
; RV64I-NEXT: xor a0, a0, a1
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: and a0, s2, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: and a0, s0, s1
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, s2
|
|
; RV64I-NEXT: call __subsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s4, 0(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%a_ = fadd half 0.0, %a ; avoid negation using xor
|
|
%b_ = fadd half 0.0, %b ; avoid negation using xor
|
|
%c_ = fadd half 0.0, %c ; avoid negation using xor
|
|
%1 = fmul contract half %a_, %b_
|
|
%2 = fneg half %1
|
|
%3 = fsub contract half %2, %c_
|
|
ret half %3
|
|
}
|
|
|
|
define half @fnmsub_s_contract(half %a, half %b, half %c) nounwind {
|
|
; RV32IZFH-LABEL: fnmsub_s_contract:
|
|
; RV32IZFH: # %bb.0:
|
|
; RV32IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV32IZFH-NEXT: fadd.h ft1, fa0, ft0
|
|
; RV32IZFH-NEXT: fadd.h ft0, fa1, ft0
|
|
; RV32IZFH-NEXT: fnmsub.h fa0, ft1, ft0, fa2
|
|
; RV32IZFH-NEXT: ret
|
|
;
|
|
; RV64IZFH-LABEL: fnmsub_s_contract:
|
|
; RV64IZFH: # %bb.0:
|
|
; RV64IZFH-NEXT: fmv.h.x ft0, zero
|
|
; RV64IZFH-NEXT: fadd.h ft1, fa0, ft0
|
|
; RV64IZFH-NEXT: fadd.h ft0, fa1, ft0
|
|
; RV64IZFH-NEXT: fnmsub.h fa0, ft1, ft0, fa2
|
|
; RV64IZFH-NEXT: ret
|
|
;
|
|
; RV32I-LABEL: fnmsub_s_contract:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -32
|
|
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
|
|
; RV32I-NEXT: mv s2, a2
|
|
; RV32I-NEXT: mv s1, a1
|
|
; RV32I-NEXT: lui a1, 16
|
|
; RV32I-NEXT: addi s0, a1, -1
|
|
; RV32I-NEXT: and a0, a0, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: and a0, s1, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, zero
|
|
; RV32I-NEXT: call __addsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s3, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: and a0, s1, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s3
|
|
; RV32I-NEXT: call __mulsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: and a0, s2, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: and a0, s1, s0
|
|
; RV32I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: mv a0, s2
|
|
; RV32I-NEXT: call __subsf3@plt
|
|
; RV32I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
|
|
; RV32I-NEXT: addi sp, sp, 32
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: fnmsub_s_contract:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -48
|
|
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
|
|
; RV64I-NEXT: mv s2, a2
|
|
; RV64I-NEXT: mv s1, a1
|
|
; RV64I-NEXT: lui a1, 16
|
|
; RV64I-NEXT: addiw s0, a1, -1
|
|
; RV64I-NEXT: and a0, a0, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: and a0, s1, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, zero
|
|
; RV64I-NEXT: call __addsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s3, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: and a0, s1, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s3
|
|
; RV64I-NEXT: call __mulsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: and a0, s2, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: and a0, s1, s0
|
|
; RV64I-NEXT: call __gnu_h2f_ieee@plt
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: mv a0, s2
|
|
; RV64I-NEXT: call __subsf3@plt
|
|
; RV64I-NEXT: call __gnu_f2h_ieee@plt
|
|
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
|
; RV64I-NEXT: addi sp, sp, 48
|
|
; RV64I-NEXT: ret
|
|
%a_ = fadd half 0.0, %a ; avoid negation using xor
|
|
%b_ = fadd half 0.0, %b ; avoid negation using xor
|
|
%1 = fmul contract half %a_, %b_
|
|
%2 = fsub contract half %c, %1
|
|
ret half %2
|
|
}
|