1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+zfh -verify-machineinstrs \
3 ; RUN: -disable-strictnode-mutation -target-abi ilp32f < %s | FileCheck %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \
5 ; RUN: -disable-strictnode-mutation -target-abi lp64f < %s | FileCheck %s
7 ; FIXME: We can't test without Zfh because soft promote legalization isn't
8 ; implemented in SelectionDAG for STRICT nodes.
10 define half @fadd_h(half %a, half %b) nounwind strictfp {
11 ; CHECK-LABEL: fadd_h:
13 ; CHECK-NEXT: fadd.h fa0, fa0, fa1
15 %1 = call half @llvm.experimental.constrained.fadd.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
18 declare half @llvm.experimental.constrained.fadd.f16(half, half, metadata, metadata)
20 define half @fsub_h(half %a, half %b) nounwind strictfp {
21 ; CHECK-LABEL: fsub_h:
23 ; CHECK-NEXT: fsub.h fa0, fa0, fa1
25 %1 = call half @llvm.experimental.constrained.fsub.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
28 declare half @llvm.experimental.constrained.fsub.f16(half, half, metadata, metadata)
30 define half @fmul_h(half %a, half %b) nounwind strictfp {
31 ; CHECK-LABEL: fmul_h:
33 ; CHECK-NEXT: fmul.h fa0, fa0, fa1
35 %1 = call half @llvm.experimental.constrained.fmul.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
38 declare half @llvm.experimental.constrained.fmul.f16(half, half, metadata, metadata)
40 define half @fdiv_h(half %a, half %b) nounwind strictfp {
41 ; CHECK-LABEL: fdiv_h:
43 ; CHECK-NEXT: fdiv.h fa0, fa0, fa1
45 %1 = call half @llvm.experimental.constrained.fdiv.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
48 declare half @llvm.experimental.constrained.fdiv.f16(half, half, metadata, metadata)
50 define half @fsqrt_h(half %a) nounwind strictfp {
51 ; CHECK-LABEL: fsqrt_h:
53 ; CHECK-NEXT: fsqrt.h fa0, fa0
55 %1 = call half @llvm.experimental.constrained.sqrt.f16(half %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
58 declare half @llvm.experimental.constrained.sqrt.f16(half, metadata, metadata)
60 ; FIXME: fminnum/fmaxnum need libcalls to handle SNaN, but we don't have f16
61 ; libcalls and don't support promotion yet.
62 ;define half @fmin_h(half %a, half %b) nounwind strictfp {
63 ; %1 = call half @llvm.experimental.constrained.minnum.f16(half %a, half %b, metadata !"fpexcept.strict") strictfp
66 ;declare half @llvm.experimental.constrained.minnum.f16(half, half, metadata) strictfp
68 ;define half @fmax_h(half %a, half %b) nounwind strictfp {
69 ; %1 = call half @llvm.experimental.constrained.maxnum.f16(half %a, half %b, metadata !"fpexcept.strict") strictfp
72 ;declare half @llvm.experimental.constrained.maxnum.f16(half, half, metadata) strictfp
74 define half @fmadd_h(half %a, half %b, half %c) nounwind strictfp {
75 ; CHECK-LABEL: fmadd_h:
77 ; CHECK-NEXT: fmadd.h fa0, fa0, fa1, fa2
79 %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %b, half %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
82 declare half @llvm.experimental.constrained.fma.f16(half, half, half, metadata, metadata) strictfp
84 define half @fmsub_h(half %a, half %b, half %c) nounwind strictfp {
85 ; CHECK-LABEL: fmsub_h:
87 ; CHECK-NEXT: fmv.h.x ft0, zero
88 ; CHECK-NEXT: fadd.h ft0, fa2, ft0
89 ; CHECK-NEXT: fmsub.h fa0, fa0, fa1, ft0
91 %c_ = fadd half 0.0, %c ; avoid negation using xor
93 %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %b, half %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
97 define half @fnmadd_h(half %a, half %b, half %c) nounwind strictfp {
98 ; CHECK-LABEL: fnmadd_h:
100 ; CHECK-NEXT: fmv.h.x ft0, zero
101 ; CHECK-NEXT: fadd.h ft1, fa0, ft0
102 ; CHECK-NEXT: fadd.h ft0, fa2, ft0
103 ; CHECK-NEXT: fnmadd.h fa0, ft1, fa1, ft0
105 %a_ = fadd half 0.0, %a
106 %c_ = fadd half 0.0, %c
107 %nega = fneg half %a_
108 %negc = fneg half %c_
109 %1 = call half @llvm.experimental.constrained.fma.f16(half %nega, half %b, half %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
113 define half @fnmadd_h_2(half %a, half %b, half %c) nounwind strictfp {
114 ; CHECK-LABEL: fnmadd_h_2:
116 ; CHECK-NEXT: fmv.h.x ft0, zero
117 ; CHECK-NEXT: fadd.h ft1, fa1, ft0
118 ; CHECK-NEXT: fadd.h ft0, fa2, ft0
119 ; CHECK-NEXT: fnmadd.h fa0, ft1, fa0, ft0
121 %b_ = fadd half 0.0, %b
122 %c_ = fadd half 0.0, %c
123 %negb = fneg half %b_
124 %negc = fneg half %c_
125 %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %negb, half %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
129 define half @fnmsub_h(half %a, half %b, half %c) nounwind strictfp {
130 ; CHECK-LABEL: fnmsub_h:
132 ; CHECK-NEXT: fmv.h.x ft0, zero
133 ; CHECK-NEXT: fadd.h ft0, fa0, ft0
134 ; CHECK-NEXT: fnmsub.h fa0, ft0, fa1, fa2
136 %a_ = fadd half 0.0, %a
137 %nega = fneg half %a_
138 %1 = call half @llvm.experimental.constrained.fma.f16(half %nega, half %b, half %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
142 define half @fnmsub_h_2(half %a, half %b, half %c) nounwind strictfp {
143 ; CHECK-LABEL: fnmsub_h_2:
145 ; CHECK-NEXT: fmv.h.x ft0, zero
146 ; CHECK-NEXT: fadd.h ft0, fa1, ft0
147 ; CHECK-NEXT: fnmsub.h fa0, ft0, fa0, fa2
149 %b_ = fadd half 0.0, %b
150 %negb = fneg half %b_
151 %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %negb, half %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp