1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -target-abi ilp32f -mattr=+zfa < %s \ 3; RUN: | FileCheck %s 4; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+zfa < %s \ 5; RUN: | FileCheck %s 6 7define float @loadfpimm1() { 8; CHECK-LABEL: loadfpimm1: 9; CHECK: # %bb.0: 10; CHECK-NEXT: fli.s fa0, 0.0625 11; CHECK-NEXT: ret 12 ret float 0.0625 13} 14 15define float @loadfpimm2() { 16; CHECK-LABEL: loadfpimm2: 17; CHECK: # %bb.0: 18; CHECK-NEXT: fli.s fa0, 0.75 19; CHECK-NEXT: ret 20 ret float 0.75 21} 22 23define float @loadfpimm3() { 24; CHECK-LABEL: loadfpimm3: 25; CHECK: # %bb.0: 26; CHECK-NEXT: fli.s fa0, 1.25 27; CHECK-NEXT: ret 28 ret float 1.25 29} 30 31define float @loadfpimm4() { 32; CHECK-LABEL: loadfpimm4: 33; CHECK: # %bb.0: 34; CHECK-NEXT: fli.s fa0, 3.0 35; CHECK-NEXT: ret 36 ret float 3.0 37} 38 39define float @loadfpimm5() { 40; CHECK-LABEL: loadfpimm5: 41; CHECK: # %bb.0: 42; CHECK-NEXT: fli.s fa0, 256.0 43; CHECK-NEXT: ret 44 ret float 256.0 45} 46 47define float @loadfpimm6() { 48; CHECK-LABEL: loadfpimm6: 49; CHECK: # %bb.0: 50; CHECK-NEXT: fli.s fa0, inf 51; CHECK-NEXT: ret 52 ret float 0x7FF0000000000000 53} 54 55define float @loadfpimm7() { 56; CHECK-LABEL: loadfpimm7: 57; CHECK: # %bb.0: 58; CHECK-NEXT: fli.s fa0, nan 59; CHECK-NEXT: ret 60 ret float 0x7FF8000000000000 61} 62 63define float @loadfpimm8() { 64; CHECK-LABEL: loadfpimm8: 65; CHECK: # %bb.0: 66; CHECK-NEXT: fli.s fa0, min 67; CHECK-NEXT: ret 68 ret float 0x3810000000000000 69} 70 71define float @loadfpimm9() { 72; CHECK-LABEL: loadfpimm9: 73; CHECK: # %bb.0: 74; CHECK-NEXT: lui a0, 276464 75; CHECK-NEXT: fmv.w.x fa0, a0 76; CHECK-NEXT: ret 77 ret float 255.0 78} 79 80; This is the f16 minimum value. Make sure we don't use fli.s. 81define float @loadfpimm10() { 82; CHECK-LABEL: loadfpimm10: 83; CHECK: # %bb.0: 84; CHECK-NEXT: lui a0, 231424 85; CHECK-NEXT: fmv.w.x fa0, a0 86; CHECK-NEXT: ret 87 ret float 0.00006103515625 88} 89 90define float @loadfpimm11() { 91; CHECK-LABEL: loadfpimm11: 92; CHECK: # %bb.0: 93; CHECK-NEXT: fli.s fa0, -1.0 94; CHECK-NEXT: ret 95 ret float -1.0 96} 97 98; Ensure fli isn't directly used for negated versions of numbers in the fli 99; table. 100define float @loadfpimm12() { 101; CHECK-LABEL: loadfpimm12: 102; CHECK: # %bb.0: 103; CHECK-NEXT: fli.s fa5, 2.0 104; CHECK-NEXT: fneg.s fa0, fa5 105; CHECK-NEXT: ret 106 ret float -2.0 107} 108 109; Ensure fli isn't directly used for negative min normal value. 110define float @loadfpimm13() { 111; CHECK-LABEL: loadfpimm13: 112; CHECK: # %bb.0: 113; CHECK-NEXT: fli.s fa5, min 114; CHECK-NEXT: fneg.s fa0, fa5 115; CHECK-NEXT: ret 116 ret float 0xb810000000000000 117} 118 119declare float @llvm.minimum.f32(float, float) 120 121define float @fminm_s(float %a, float %b) nounwind { 122; CHECK-LABEL: fminm_s: 123; CHECK: # %bb.0: 124; CHECK-NEXT: fminm.s fa0, fa0, fa1 125; CHECK-NEXT: ret 126 %1 = call float @llvm.minimum.f32(float %a, float %b) 127 ret float %1 128} 129 130declare float @llvm.maximum.f32(float, float) 131 132define float @fmaxm_s(float %a, float %b) nounwind { 133; CHECK-LABEL: fmaxm_s: 134; CHECK: # %bb.0: 135; CHECK-NEXT: fmaxm.s fa0, fa0, fa1 136; CHECK-NEXT: ret 137 %1 = call float @llvm.maximum.f32(float %a, float %b) 138 ret float %1 139} 140 141 142define float @fround_s_1(float %a) nounwind { 143; CHECK-LABEL: fround_s_1: 144; CHECK: # %bb.0: 145; CHECK-NEXT: fround.s fa0, fa0, rmm 146; CHECK-NEXT: ret 147 %call = tail call float @roundf(float %a) nounwind readnone 148 ret float %call 149} 150 151declare float @roundf(float) nounwind readnone 152 153 154define float @fround_s_2(float %a) nounwind { 155; CHECK-LABEL: fround_s_2: 156; CHECK: # %bb.0: 157; CHECK-NEXT: fround.s fa0, fa0, rdn 158; CHECK-NEXT: ret 159 %call = tail call float @floorf(float %a) nounwind readnone 160 ret float %call 161} 162 163declare float @floorf(float) nounwind readnone 164 165 166define float @fround_s_3(float %a) nounwind { 167; CHECK-LABEL: fround_s_3: 168; CHECK: # %bb.0: 169; CHECK-NEXT: fround.s fa0, fa0, rup 170; CHECK-NEXT: ret 171 %call = tail call float @ceilf(float %a) nounwind readnone 172 ret float %call 173} 174 175declare float @ceilf(float) nounwind readnone 176 177 178define float @fround_s_4(float %a) nounwind { 179; CHECK-LABEL: fround_s_4: 180; CHECK: # %bb.0: 181; CHECK-NEXT: fround.s fa0, fa0, rtz 182; CHECK-NEXT: ret 183 %call = tail call float @truncf(float %a) nounwind readnone 184 ret float %call 185} 186 187declare float @truncf(float) nounwind readnone 188 189 190define float @fround_s_5(float %a) nounwind { 191; CHECK-LABEL: fround_s_5: 192; CHECK: # %bb.0: 193; CHECK-NEXT: fround.s fa0, fa0 194; CHECK-NEXT: ret 195 %call = tail call float @nearbyintf(float %a) nounwind readnone 196 ret float %call 197} 198 199declare float @nearbyintf(float) nounwind readnone 200 201define float @fround_s_6(float %a) nounwind { 202; CHECK-LABEL: fround_s_6: 203; CHECK: # %bb.0: 204; CHECK-NEXT: fround.s fa0, fa0, rne 205; CHECK-NEXT: ret 206 %call = tail call float @llvm.roundeven.f32(float %a) nounwind readnone 207 ret float %call 208} 209 210declare float @llvm.roundeven.f32(float) nounwind readnone 211 212 213define float @froundnx_s(float %a) nounwind { 214; CHECK-LABEL: froundnx_s: 215; CHECK: # %bb.0: 216; CHECK-NEXT: froundnx.s fa0, fa0 217; CHECK-NEXT: ret 218 %call = tail call float @rintf(float %a) nounwind readnone 219 ret float %call 220} 221 222declare float @rintf(float) nounwind readnone 223 224declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata) 225 226define i32 @fcmp_olt_q(float %a, float %b) nounwind strictfp { 227; CHECK-LABEL: fcmp_olt_q: 228; CHECK: # %bb.0: 229; CHECK-NEXT: fltq.s a0, fa0, fa1 230; CHECK-NEXT: ret 231 %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"olt", metadata !"fpexcept.strict") strictfp 232 %2 = zext i1 %1 to i32 233 ret i32 %2 234} 235 236define i32 @fcmp_ole_q(float %a, float %b) nounwind strictfp { 237; CHECK-LABEL: fcmp_ole_q: 238; CHECK: # %bb.0: 239; CHECK-NEXT: fleq.s a0, fa0, fa1 240; CHECK-NEXT: ret 241 %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ole", metadata !"fpexcept.strict") strictfp 242 %2 = zext i1 %1 to i32 243 ret i32 %2 244} 245 246define i32 @fcmp_one_q(float %a, float %b) nounwind strictfp { 247; CHECK-LABEL: fcmp_one_q: 248; CHECK: # %bb.0: 249; CHECK-NEXT: fltq.s a0, fa0, fa1 250; CHECK-NEXT: fltq.s a1, fa1, fa0 251; CHECK-NEXT: or a0, a1, a0 252; CHECK-NEXT: ret 253 %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"one", metadata !"fpexcept.strict") strictfp 254 %2 = zext i1 %1 to i32 255 ret i32 %2 256} 257 258define i32 @fcmp_ueq_q(float %a, float %b) nounwind strictfp { 259; CHECK-LABEL: fcmp_ueq_q: 260; CHECK: # %bb.0: 261; CHECK-NEXT: fltq.s a0, fa0, fa1 262; CHECK-NEXT: fltq.s a1, fa1, fa0 263; CHECK-NEXT: or a0, a1, a0 264; CHECK-NEXT: xori a0, a0, 1 265; CHECK-NEXT: ret 266 %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp 267 %2 = zext i1 %1 to i32 268 ret i32 %2 269} 270 271declare void @foo(float, float) 272 273; Make sure we use two fli instructions instead of copying. 274define void @fli_remat() { 275; CHECK-LABEL: fli_remat: 276; CHECK: # %bb.0: 277; CHECK-NEXT: fli.s fa0, 1.0 278; CHECK-NEXT: fli.s fa1, 1.0 279; CHECK-NEXT: tail foo 280 tail call void @foo(float 1.000000e+00, float 1.000000e+00) 281 ret void 282} 283 284define float @fadd_neg_0p5(float %x) { 285; CHECK-LABEL: fadd_neg_0p5: 286; CHECK: # %bb.0: 287; CHECK-NEXT: fli.s fa5, 0.5 288; CHECK-NEXT: fsub.s fa0, fa0, fa5 289; CHECK-NEXT: ret 290 %a = fadd float %x, -0.5 291 ret float %a 292} 293 294define float @fma_neg_addend(float %x, float %y) nounwind { 295; CHECK-LABEL: fma_neg_addend: 296; CHECK: # %bb.0: 297; CHECK-NEXT: fli.s fa5, 0.5 298; CHECK-NEXT: fmsub.s fa0, fa0, fa1, fa5 299; CHECK-NEXT: ret 300 %a = call float @llvm.fma.f32(float %x, float %y, float -0.5) 301 ret float %a 302} 303 304define float @fma_neg_multiplicand(float %x, float %y) nounwind { 305; CHECK-LABEL: fma_neg_multiplicand: 306; CHECK: # %bb.0: 307; CHECK-NEXT: fli.s fa5, 0.125 308; CHECK-NEXT: fnmsub.s fa0, fa5, fa0, fa1 309; CHECK-NEXT: ret 310 %a = call float @llvm.fma.f32(float %x, float -0.125, float %y) 311 ret float %a 312} 313 314define float @fma_neg_addend_multiplicand(float %x) nounwind { 315; CHECK-LABEL: fma_neg_addend_multiplicand: 316; CHECK: # %bb.0: 317; CHECK-NEXT: fli.s fa5, 0.25 318; CHECK-NEXT: fli.s fa4, 0.5 319; CHECK-NEXT: fnmadd.s fa0, fa4, fa0, fa5 320; CHECK-NEXT: ret 321 %a = call float @llvm.fma.f32(float %x, float -0.5, float -0.25) 322 ret float %a 323} 324 325define float @select_loadfpimm(float %x) nounwind { 326; CHECK-LABEL: select_loadfpimm: 327; CHECK: # %bb.0: # %entry 328; CHECK-NEXT: fmv.w.x fa5, zero 329; CHECK-NEXT: fle.s a0, fa5, fa0 330; CHECK-NEXT: fli.s fa0, 0.5 331; CHECK-NEXT: bnez a0, .LBB31_2 332; CHECK-NEXT: # %bb.1: 333; CHECK-NEXT: fneg.s fa0, fa0 334; CHECK-NEXT: .LBB31_2: # %entry 335; CHECK-NEXT: ret 336entry: 337 %cmp = fcmp ult float %x, 0.000000e+00 338 %sel = select i1 %cmp, float -5.000000e-01, float 5.000000e-01 339 ret float %sel 340} 341