152 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \3; RUN: | FileCheck -check-prefix=RV32I %s4; RUN: llc -mtriple=riscv32 -target-abi ilp32 -mattr=+f -verify-machineinstrs < %s \5; RUN: | FileCheck -check-prefix=RV32IF %s6; RUN: llc -mtriple=riscv32 -target-abi ilp32 -mattr=+zfinx -verify-machineinstrs < %s \7; RUN: | FileCheck -check-prefix=RV32IZFINX %s8; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \9; RUN: | FileCheck -check-prefix=RV64I %s10; RUN: llc -mtriple=riscv64 -target-abi lp64 -mattr=+f -verify-machineinstrs < %s \11; RUN: | FileCheck -check-prefix=RV64IF %s12; RUN: llc -mtriple=riscv64 -target-abi lp64 -mattr=+zfinx -verify-machineinstrs < %s \13; RUN: | FileCheck -check-prefix=RV64IZFINX %s14 15; This file tests cases where simple floating point operations can be16; profitably handled though bit manipulation if a soft-float ABI is being used17; (e.g. fneg implemented by XORing the sign bit). This is typically handled in18; DAGCombiner::visitBITCAST, but this target-independent code may not trigger19; in cases where we perform custom legalisation (e.g. RV64F).20 21define float @fneg(float %a) nounwind {22; RV32I-LABEL: fneg:23; RV32I: # %bb.0:24; RV32I-NEXT: lui a1, 52428825; RV32I-NEXT: xor a0, a0, a126; RV32I-NEXT: ret27;28; RV32IF-LABEL: fneg:29; RV32IF: # %bb.0:30; RV32IF-NEXT: lui a1, 52428831; RV32IF-NEXT: xor a0, a0, a132; RV32IF-NEXT: ret33;34; RV32IZFINX-LABEL: fneg:35; RV32IZFINX: # %bb.0:36; RV32IZFINX-NEXT: fneg.s a0, a037; RV32IZFINX-NEXT: ret38;39; RV64I-LABEL: fneg:40; RV64I: # %bb.0:41; RV64I-NEXT: lui a1, 52428842; RV64I-NEXT: xor a0, a0, a143; RV64I-NEXT: ret44;45; RV64IF-LABEL: fneg:46; RV64IF: # %bb.0:47; RV64IF-NEXT: lui a1, 52428848; RV64IF-NEXT: xor a0, a0, a149; RV64IF-NEXT: ret50;51; RV64IZFINX-LABEL: fneg:52; RV64IZFINX: # %bb.0:53; RV64IZFINX-NEXT: fneg.s a0, a054; RV64IZFINX-NEXT: ret55 %1 = fneg float %a56 ret float %157}58 59define float @fabs(float %a) nounwind {60; RV32I-LABEL: fabs:61; RV32I: # %bb.0:62; RV32I-NEXT: slli a0, a0, 163; RV32I-NEXT: srli a0, a0, 164; RV32I-NEXT: ret65;66; RV32IF-LABEL: fabs:67; RV32IF: # %bb.0:68; RV32IF-NEXT: slli a0, a0, 169; RV32IF-NEXT: srli a0, a0, 170; RV32IF-NEXT: ret71;72; RV32IZFINX-LABEL: fabs:73; RV32IZFINX: # %bb.0:74; RV32IZFINX-NEXT: fabs.s a0, a075; RV32IZFINX-NEXT: ret76;77; RV64I-LABEL: fabs:78; RV64I: # %bb.0:79; RV64I-NEXT: slli a0, a0, 3380; RV64I-NEXT: srli a0, a0, 3381; RV64I-NEXT: ret82;83; RV64IF-LABEL: fabs:84; RV64IF: # %bb.0:85; RV64IF-NEXT: slli a0, a0, 3386; RV64IF-NEXT: srli a0, a0, 3387; RV64IF-NEXT: ret88;89; RV64IZFINX-LABEL: fabs:90; RV64IZFINX: # %bb.0:91; RV64IZFINX-NEXT: fabs.s a0, a092; RV64IZFINX-NEXT: ret93 %1 = call float @llvm.fabs.f32(float %a)94 ret float %195}96 97; DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN will convert to bitwise98; operations if floating point isn't supported. A combine could be written to99; do the same even when f32 is legal.100 101define float @fcopysign_fneg(float %a, float %b) nounwind {102; RV32I-LABEL: fcopysign_fneg:103; RV32I: # %bb.0:104; RV32I-NEXT: not a1, a1105; RV32I-NEXT: lui a2, 524288106; RV32I-NEXT: slli a0, a0, 1107; RV32I-NEXT: and a1, a1, a2108; RV32I-NEXT: srli a0, a0, 1109; RV32I-NEXT: or a0, a0, a1110; RV32I-NEXT: ret111;112; RV32IF-LABEL: fcopysign_fneg:113; RV32IF: # %bb.0:114; RV32IF-NEXT: fmv.w.x fa5, a0115; RV32IF-NEXT: not a0, a1116; RV32IF-NEXT: fmv.w.x fa4, a0117; RV32IF-NEXT: fsgnj.s fa5, fa5, fa4118; RV32IF-NEXT: fmv.x.w a0, fa5119; RV32IF-NEXT: ret120;121; RV32IZFINX-LABEL: fcopysign_fneg:122; RV32IZFINX: # %bb.0:123; RV32IZFINX-NEXT: fsgnjn.s a0, a0, a1124; RV32IZFINX-NEXT: ret125;126; RV64I-LABEL: fcopysign_fneg:127; RV64I: # %bb.0:128; RV64I-NEXT: not a1, a1129; RV64I-NEXT: lui a2, 524288130; RV64I-NEXT: slli a0, a0, 33131; RV64I-NEXT: and a1, a1, a2132; RV64I-NEXT: srli a0, a0, 33133; RV64I-NEXT: or a0, a0, a1134; RV64I-NEXT: ret135;136; RV64IF-LABEL: fcopysign_fneg:137; RV64IF: # %bb.0:138; RV64IF-NEXT: fmv.w.x fa5, a1139; RV64IF-NEXT: fmv.w.x fa4, a0140; RV64IF-NEXT: fsgnjn.s fa5, fa4, fa5141; RV64IF-NEXT: fmv.x.w a0, fa5142; RV64IF-NEXT: ret143;144; RV64IZFINX-LABEL: fcopysign_fneg:145; RV64IZFINX: # %bb.0:146; RV64IZFINX-NEXT: fsgnjn.s a0, a0, a1147; RV64IZFINX-NEXT: ret148 %1 = fneg float %b149 %2 = call float @llvm.copysign.f32(float %a, float %1)150 ret float %2151}152