1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32IF %s 4; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV32IF %s 6 7declare float @llvm.sqrt.f32(float) 8 9define float @sqrt_f32(float %a) nounwind { 10; RV32IF-LABEL: sqrt_f32: 11; RV32IF: # %bb.0: 12; RV32IF-NEXT: fmv.w.x ft0, a0 13; RV32IF-NEXT: fsqrt.s ft0, ft0 14; RV32IF-NEXT: fmv.x.w a0, ft0 15; RV32IF-NEXT: ret 16 %1 = call float @llvm.sqrt.f32(float %a) 17 ret float %1 18} 19 20declare float @llvm.powi.f32(float, i32) 21 22define float @powi_f32(float %a, i32 %b) nounwind { 23; RV32IF-LABEL: powi_f32: 24; RV32IF: # %bb.0: 25; RV32IF-NEXT: addi sp, sp, -16 26; RV32IF-NEXT: sw ra, 12(sp) 27; RV32IF-NEXT: call __powisf2 28; RV32IF-NEXT: lw ra, 12(sp) 29; RV32IF-NEXT: addi sp, sp, 16 30; RV32IF-NEXT: ret 31 %1 = call float @llvm.powi.f32(float %a, i32 %b) 32 ret float %1 33} 34 35declare float @llvm.sin.f32(float) 36 37define float @sin_f32(float %a) nounwind { 38; RV32IF-LABEL: sin_f32: 39; RV32IF: # %bb.0: 40; RV32IF-NEXT: addi sp, sp, -16 41; RV32IF-NEXT: sw ra, 12(sp) 42; RV32IF-NEXT: call sinf 43; RV32IF-NEXT: lw ra, 12(sp) 44; RV32IF-NEXT: addi sp, sp, 16 45; RV32IF-NEXT: ret 46 %1 = call float @llvm.sin.f32(float %a) 47 ret float %1 48} 49 50declare float @llvm.cos.f32(float) 51 52define float @cos_f32(float %a) nounwind { 53; RV32IF-LABEL: cos_f32: 54; RV32IF: # %bb.0: 55; RV32IF-NEXT: addi sp, sp, -16 56; RV32IF-NEXT: sw ra, 12(sp) 57; RV32IF-NEXT: call cosf 58; RV32IF-NEXT: lw ra, 12(sp) 59; RV32IF-NEXT: addi sp, sp, 16 60; RV32IF-NEXT: ret 61 %1 = call float @llvm.cos.f32(float %a) 62 ret float %1 63} 64 65; The sin+cos combination results in an FSINCOS SelectionDAG node. 66define float @sincos_f32(float %a) nounwind { 67; RV32IF-LABEL: sincos_f32: 68; RV32IF: # %bb.0: 69; RV32IF-NEXT: addi sp, sp, -16 70; RV32IF-NEXT: sw ra, 12(sp) 71; RV32IF-NEXT: sw s1, 8(sp) 72; RV32IF-NEXT: sw s2, 4(sp) 73; RV32IF-NEXT: mv s1, a0 74; RV32IF-NEXT: call sinf 75; RV32IF-NEXT: mv s2, a0 76; RV32IF-NEXT: mv a0, s1 77; RV32IF-NEXT: call cosf 78; RV32IF-NEXT: fmv.w.x ft0, a0 79; RV32IF-NEXT: fmv.w.x ft1, s2 80; RV32IF-NEXT: fadd.s ft0, ft1, ft0 81; RV32IF-NEXT: fmv.x.w a0, ft0 82; RV32IF-NEXT: lw s2, 4(sp) 83; RV32IF-NEXT: lw s1, 8(sp) 84; RV32IF-NEXT: lw ra, 12(sp) 85; RV32IF-NEXT: addi sp, sp, 16 86; RV32IF-NEXT: ret 87 %1 = call float @llvm.sin.f32(float %a) 88 %2 = call float @llvm.cos.f32(float %a) 89 %3 = fadd float %1, %2 90 ret float %3 91} 92 93declare float @llvm.pow.f32(float, float) 94 95define float @pow_f32(float %a, float %b) nounwind { 96; RV32IF-LABEL: pow_f32: 97; RV32IF: # %bb.0: 98; RV32IF-NEXT: addi sp, sp, -16 99; RV32IF-NEXT: sw ra, 12(sp) 100; RV32IF-NEXT: call powf 101; RV32IF-NEXT: lw ra, 12(sp) 102; RV32IF-NEXT: addi sp, sp, 16 103; RV32IF-NEXT: ret 104 %1 = call float @llvm.pow.f32(float %a, float %b) 105 ret float %1 106} 107 108declare float @llvm.exp.f32(float) 109 110define float @exp_f32(float %a) nounwind { 111; RV32IF-LABEL: exp_f32: 112; RV32IF: # %bb.0: 113; RV32IF-NEXT: addi sp, sp, -16 114; RV32IF-NEXT: sw ra, 12(sp) 115; RV32IF-NEXT: call expf 116; RV32IF-NEXT: lw ra, 12(sp) 117; RV32IF-NEXT: addi sp, sp, 16 118; RV32IF-NEXT: ret 119 %1 = call float @llvm.exp.f32(float %a) 120 ret float %1 121} 122 123declare float @llvm.exp2.f32(float) 124 125define float @exp2_f32(float %a) nounwind { 126; RV32IF-LABEL: exp2_f32: 127; RV32IF: # %bb.0: 128; RV32IF-NEXT: addi sp, sp, -16 129; RV32IF-NEXT: sw ra, 12(sp) 130; RV32IF-NEXT: call exp2f 131; RV32IF-NEXT: lw ra, 12(sp) 132; RV32IF-NEXT: addi sp, sp, 16 133; RV32IF-NEXT: ret 134 %1 = call float @llvm.exp2.f32(float %a) 135 ret float %1 136} 137 138declare float @llvm.log.f32(float) 139 140define float @log_f32(float %a) nounwind { 141; RV32IF-LABEL: log_f32: 142; RV32IF: # %bb.0: 143; RV32IF-NEXT: addi sp, sp, -16 144; RV32IF-NEXT: sw ra, 12(sp) 145; RV32IF-NEXT: call logf 146; RV32IF-NEXT: lw ra, 12(sp) 147; RV32IF-NEXT: addi sp, sp, 16 148; RV32IF-NEXT: ret 149 %1 = call float @llvm.log.f32(float %a) 150 ret float %1 151} 152 153declare float @llvm.log10.f32(float) 154 155define float @log10_f32(float %a) nounwind { 156; RV32IF-LABEL: log10_f32: 157; RV32IF: # %bb.0: 158; RV32IF-NEXT: addi sp, sp, -16 159; RV32IF-NEXT: sw ra, 12(sp) 160; RV32IF-NEXT: call log10f 161; RV32IF-NEXT: lw ra, 12(sp) 162; RV32IF-NEXT: addi sp, sp, 16 163; RV32IF-NEXT: ret 164 %1 = call float @llvm.log10.f32(float %a) 165 ret float %1 166} 167 168declare float @llvm.log2.f32(float) 169 170define float @log2_f32(float %a) nounwind { 171; RV32IF-LABEL: log2_f32: 172; RV32IF: # %bb.0: 173; RV32IF-NEXT: addi sp, sp, -16 174; RV32IF-NEXT: sw ra, 12(sp) 175; RV32IF-NEXT: call log2f 176; RV32IF-NEXT: lw ra, 12(sp) 177; RV32IF-NEXT: addi sp, sp, 16 178; RV32IF-NEXT: ret 179 %1 = call float @llvm.log2.f32(float %a) 180 ret float %1 181} 182 183declare float @llvm.fma.f32(float, float, float) 184 185define float @fma_f32(float %a, float %b, float %c) nounwind { 186; RV32IF-LABEL: fma_f32: 187; RV32IF: # %bb.0: 188; RV32IF-NEXT: fmv.w.x ft0, a2 189; RV32IF-NEXT: fmv.w.x ft1, a1 190; RV32IF-NEXT: fmv.w.x ft2, a0 191; RV32IF-NEXT: fmadd.s ft0, ft2, ft1, ft0 192; RV32IF-NEXT: fmv.x.w a0, ft0 193; RV32IF-NEXT: ret 194 %1 = call float @llvm.fma.f32(float %a, float %b, float %c) 195 ret float %1 196} 197 198declare float @llvm.fmuladd.f32(float, float, float) 199 200define float @fmuladd_f32(float %a, float %b, float %c) nounwind { 201; Use of fmadd depends on TargetLowering::isFMAFasterthanFMulAndFAdd 202; RV32IF-LABEL: fmuladd_f32: 203; RV32IF: # %bb.0: 204; RV32IF-NEXT: fmv.w.x ft0, a1 205; RV32IF-NEXT: fmv.w.x ft1, a0 206; RV32IF-NEXT: fmul.s ft0, ft1, ft0 207; RV32IF-NEXT: fmv.w.x ft1, a2 208; RV32IF-NEXT: fadd.s ft0, ft0, ft1 209; RV32IF-NEXT: fmv.x.w a0, ft0 210; RV32IF-NEXT: ret 211 %1 = call float @llvm.fmuladd.f32(float %a, float %b, float %c) 212 ret float %1 213} 214 215declare float @llvm.fabs.f32(float) 216 217define float @fabs_f32(float %a) nounwind { 218; RV32IF-LABEL: fabs_f32: 219; RV32IF: # %bb.0: 220; RV32IF-NEXT: lui a1, 524288 221; RV32IF-NEXT: addi a1, a1, -1 222; RV32IF-NEXT: and a0, a0, a1 223; RV32IF-NEXT: ret 224 %1 = call float @llvm.fabs.f32(float %a) 225 ret float %1 226} 227 228declare float @llvm.minnum.f32(float, float) 229 230define float @minnum_f32(float %a, float %b) nounwind { 231; RV32IF-LABEL: minnum_f32: 232; RV32IF: # %bb.0: 233; RV32IF-NEXT: fmv.w.x ft0, a1 234; RV32IF-NEXT: fmv.w.x ft1, a0 235; RV32IF-NEXT: fmin.s ft0, ft1, ft0 236; RV32IF-NEXT: fmv.x.w a0, ft0 237; RV32IF-NEXT: ret 238 %1 = call float @llvm.minnum.f32(float %a, float %b) 239 ret float %1 240} 241 242declare float @llvm.maxnum.f32(float, float) 243 244define float @maxnum_f32(float %a, float %b) nounwind { 245; RV32IF-LABEL: maxnum_f32: 246; RV32IF: # %bb.0: 247; RV32IF-NEXT: fmv.w.x ft0, a1 248; RV32IF-NEXT: fmv.w.x ft1, a0 249; RV32IF-NEXT: fmax.s ft0, ft1, ft0 250; RV32IF-NEXT: fmv.x.w a0, ft0 251; RV32IF-NEXT: ret 252 %1 = call float @llvm.maxnum.f32(float %a, float %b) 253 ret float %1 254} 255 256; TODO: FMINNAN and FMAXNAN aren't handled in 257; SelectionDAGLegalize::ExpandNode. 258 259; declare float @llvm.minimum.f32(float, float) 260 261; define float @fminimum_f32(float %a, float %b) nounwind { 262; %1 = call float @llvm.minimum.f32(float %a, float %b) 263; ret float %1 264; } 265 266; declare float @llvm.maximum.f32(float, float) 267 268; define float @fmaximum_f32(float %a, float %b) nounwind { 269; %1 = call float @llvm.maximum.f32(float %a, float %b) 270; ret float %1 271; } 272 273declare float @llvm.copysign.f32(float, float) 274 275define float @copysign_f32(float %a, float %b) nounwind { 276; RV32IF-LABEL: copysign_f32: 277; RV32IF: # %bb.0: 278; RV32IF-NEXT: fmv.w.x ft0, a1 279; RV32IF-NEXT: fmv.w.x ft1, a0 280; RV32IF-NEXT: fsgnj.s ft0, ft1, ft0 281; RV32IF-NEXT: fmv.x.w a0, ft0 282; RV32IF-NEXT: ret 283 %1 = call float @llvm.copysign.f32(float %a, float %b) 284 ret float %1 285} 286 287declare float @llvm.floor.f32(float) 288 289define float @floor_f32(float %a) nounwind { 290; RV32IF-LABEL: floor_f32: 291; RV32IF: # %bb.0: 292; RV32IF-NEXT: addi sp, sp, -16 293; RV32IF-NEXT: sw ra, 12(sp) 294; RV32IF-NEXT: call floorf 295; RV32IF-NEXT: lw ra, 12(sp) 296; RV32IF-NEXT: addi sp, sp, 16 297; RV32IF-NEXT: ret 298 %1 = call float @llvm.floor.f32(float %a) 299 ret float %1 300} 301 302declare float @llvm.ceil.f32(float) 303 304define float @ceil_f32(float %a) nounwind { 305; RV32IF-LABEL: ceil_f32: 306; RV32IF: # %bb.0: 307; RV32IF-NEXT: addi sp, sp, -16 308; RV32IF-NEXT: sw ra, 12(sp) 309; RV32IF-NEXT: call ceilf 310; RV32IF-NEXT: lw ra, 12(sp) 311; RV32IF-NEXT: addi sp, sp, 16 312; RV32IF-NEXT: ret 313 %1 = call float @llvm.ceil.f32(float %a) 314 ret float %1 315} 316 317declare float @llvm.trunc.f32(float) 318 319define float @trunc_f32(float %a) nounwind { 320; RV32IF-LABEL: trunc_f32: 321; RV32IF: # %bb.0: 322; RV32IF-NEXT: addi sp, sp, -16 323; RV32IF-NEXT: sw ra, 12(sp) 324; RV32IF-NEXT: call truncf 325; RV32IF-NEXT: lw ra, 12(sp) 326; RV32IF-NEXT: addi sp, sp, 16 327; RV32IF-NEXT: ret 328 %1 = call float @llvm.trunc.f32(float %a) 329 ret float %1 330} 331 332declare float @llvm.rint.f32(float) 333 334define float @rint_f32(float %a) nounwind { 335; RV32IF-LABEL: rint_f32: 336; RV32IF: # %bb.0: 337; RV32IF-NEXT: addi sp, sp, -16 338; RV32IF-NEXT: sw ra, 12(sp) 339; RV32IF-NEXT: call rintf 340; RV32IF-NEXT: lw ra, 12(sp) 341; RV32IF-NEXT: addi sp, sp, 16 342; RV32IF-NEXT: ret 343 %1 = call float @llvm.rint.f32(float %a) 344 ret float %1 345} 346 347declare float @llvm.nearbyint.f32(float) 348 349define float @nearbyint_f32(float %a) nounwind { 350; RV32IF-LABEL: nearbyint_f32: 351; RV32IF: # %bb.0: 352; RV32IF-NEXT: addi sp, sp, -16 353; RV32IF-NEXT: sw ra, 12(sp) 354; RV32IF-NEXT: call nearbyintf 355; RV32IF-NEXT: lw ra, 12(sp) 356; RV32IF-NEXT: addi sp, sp, 16 357; RV32IF-NEXT: ret 358 %1 = call float @llvm.nearbyint.f32(float %a) 359 ret float %1 360} 361 362declare float @llvm.round.f32(float) 363 364define float @round_f32(float %a) nounwind { 365; RV32IF-LABEL: round_f32: 366; RV32IF: # %bb.0: 367; RV32IF-NEXT: addi sp, sp, -16 368; RV32IF-NEXT: sw ra, 12(sp) 369; RV32IF-NEXT: call roundf 370; RV32IF-NEXT: lw ra, 12(sp) 371; RV32IF-NEXT: addi sp, sp, 16 372; RV32IF-NEXT: ret 373 %1 = call float @llvm.round.f32(float %a) 374 ret float %1 375} 376