255 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=+zfh -verify-machineinstrs \5; RUN: < %s | FileCheck -check-prefix=RV32IZFH %s6; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \7; RUN: | FileCheck -check-prefix=RV64I %s8; RUN: llc -mtriple=riscv64 -target-abi lp64 -mattr=+zfh -verify-machineinstrs \9; RUN: < %s | FileCheck -check-prefix=RV64IZFH %s10; RUN: llc -mtriple=riscv32 -target-abi ilp32 -mattr=+zhinx -verify-machineinstrs \11; RUN: < %s | FileCheck -check-prefix=RV32IZHINX %s12; RUN: llc -mtriple=riscv64 -target-abi lp64 -mattr=+zhinx -verify-machineinstrs \13; RUN: < %s | FileCheck -check-prefix=RV64IZHINX %s14; RUN: llc -mtriple=riscv32 -target-abi ilp32 -mattr=+zfhmin -verify-machineinstrs \15; RUN: < %s | FileCheck -check-prefix=RV32IZFHMIN %s16; RUN: llc -mtriple=riscv64 -target-abi lp64 -verify-machineinstrs < %s \17; RUN: | FileCheck -check-prefix=RV64I %s18; RUN: llc -mtriple=riscv64 -target-abi lp64 -mattr=+zfhmin -verify-machineinstrs \19; RUN: < %s | FileCheck -check-prefix=RV64IZFHMIN %s20; RUN: llc -mtriple=riscv32 -target-abi ilp32 -mattr=+zhinxmin -verify-machineinstrs \21; RUN: < %s | FileCheck --check-prefixes=RVIZHINXMIN,RV32IZHINXMIN %s22; RUN: llc -mtriple=riscv64 -target-abi lp64 -mattr=+zhinxmin -verify-machineinstrs \23; RUN: < %s | FileCheck --check-prefixes=RVIZHINXMIN,RV64IZHINXMIN %s24 25; This file tests cases where simple floating point operations can be26; profitably handled though bit manipulation if a soft-float ABI is being used27; (e.g. fneg implemented by XORing the sign bit). This is typically handled in28; DAGCombiner::visitBITCAST, but this target-independent code may not trigger29; in cases where we perform custom legalisation (e.g. RV64F).30 31define half @fneg(half %a) nounwind {32; RV32I-LABEL: fneg:33; RV32I: # %bb.0:34; RV32I-NEXT: lui a1, 104856835; RV32I-NEXT: xor a0, a0, a136; RV32I-NEXT: ret37;38; RV32IZFH-LABEL: fneg:39; RV32IZFH: # %bb.0:40; RV32IZFH-NEXT: lui a1, 104856841; RV32IZFH-NEXT: xor a0, a0, a142; RV32IZFH-NEXT: ret43;44; RV64I-LABEL: fneg:45; RV64I: # %bb.0:46; RV64I-NEXT: lui a1, 104856847; RV64I-NEXT: xor a0, a0, a148; RV64I-NEXT: ret49;50; RV64IZFH-LABEL: fneg:51; RV64IZFH: # %bb.0:52; RV64IZFH-NEXT: lui a1, 104856853; RV64IZFH-NEXT: xor a0, a0, a154; RV64IZFH-NEXT: ret55;56; RV32IZHINX-LABEL: fneg:57; RV32IZHINX: # %bb.0:58; RV32IZHINX-NEXT: fneg.h a0, a059; RV32IZHINX-NEXT: ret60;61; RV64IZHINX-LABEL: fneg:62; RV64IZHINX: # %bb.0:63; RV64IZHINX-NEXT: fneg.h a0, a064; RV64IZHINX-NEXT: ret65;66; RV32IZFHMIN-LABEL: fneg:67; RV32IZFHMIN: # %bb.0:68; RV32IZFHMIN-NEXT: lui a1, 104856869; RV32IZFHMIN-NEXT: xor a0, a0, a170; RV32IZFHMIN-NEXT: ret71;72; RV64IZFHMIN-LABEL: fneg:73; RV64IZFHMIN: # %bb.0:74; RV64IZFHMIN-NEXT: lui a1, 104856875; RV64IZFHMIN-NEXT: xor a0, a0, a176; RV64IZFHMIN-NEXT: ret77;78; RVIZHINXMIN-LABEL: fneg:79; RVIZHINXMIN: # %bb.0:80; RVIZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h def $x1081; RVIZHINXMIN-NEXT: lui a1, 104856882; RVIZHINXMIN-NEXT: xor a0, a0, a183; RVIZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h killed $x1084; RVIZHINXMIN-NEXT: ret85 %1 = fneg half %a86 ret half %187}88 89define half @fabs(half %a) nounwind {90; RV32I-LABEL: fabs:91; RV32I: # %bb.0:92; RV32I-NEXT: slli a0, a0, 1793; RV32I-NEXT: srli a0, a0, 1794; RV32I-NEXT: ret95;96; RV32IZFH-LABEL: fabs:97; RV32IZFH: # %bb.0:98; RV32IZFH-NEXT: slli a0, a0, 1799; RV32IZFH-NEXT: srli a0, a0, 17100; RV32IZFH-NEXT: ret101;102; RV64I-LABEL: fabs:103; RV64I: # %bb.0:104; RV64I-NEXT: slli a0, a0, 49105; RV64I-NEXT: srli a0, a0, 49106; RV64I-NEXT: ret107;108; RV64IZFH-LABEL: fabs:109; RV64IZFH: # %bb.0:110; RV64IZFH-NEXT: slli a0, a0, 49111; RV64IZFH-NEXT: srli a0, a0, 49112; RV64IZFH-NEXT: ret113;114; RV32IZHINX-LABEL: fabs:115; RV32IZHINX: # %bb.0:116; RV32IZHINX-NEXT: fabs.h a0, a0117; RV32IZHINX-NEXT: ret118;119; RV64IZHINX-LABEL: fabs:120; RV64IZHINX: # %bb.0:121; RV64IZHINX-NEXT: fabs.h a0, a0122; RV64IZHINX-NEXT: ret123;124; RV32IZFHMIN-LABEL: fabs:125; RV32IZFHMIN: # %bb.0:126; RV32IZFHMIN-NEXT: slli a0, a0, 17127; RV32IZFHMIN-NEXT: srli a0, a0, 17128; RV32IZFHMIN-NEXT: ret129;130; RV64IZFHMIN-LABEL: fabs:131; RV64IZFHMIN: # %bb.0:132; RV64IZFHMIN-NEXT: slli a0, a0, 49133; RV64IZFHMIN-NEXT: srli a0, a0, 49134; RV64IZFHMIN-NEXT: ret135;136; RV32IZHINXMIN-LABEL: fabs:137; RV32IZHINXMIN: # %bb.0:138; RV32IZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h def $x10139; RV32IZHINXMIN-NEXT: slli a0, a0, 17140; RV32IZHINXMIN-NEXT: srli a0, a0, 17141; RV32IZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h killed $x10142; RV32IZHINXMIN-NEXT: ret143;144; RV64IZHINXMIN-LABEL: fabs:145; RV64IZHINXMIN: # %bb.0:146; RV64IZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h def $x10147; RV64IZHINXMIN-NEXT: slli a0, a0, 49148; RV64IZHINXMIN-NEXT: srli a0, a0, 49149; RV64IZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h killed $x10150; RV64IZHINXMIN-NEXT: ret151 %1 = call half @llvm.fabs.f16(half %a)152 ret half %1153}154 155; DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN will convert to bitwise156; operations if half precision floating point isn't supported. A combine could157; be written to do the same even when f16 is legal.158 159define half @fcopysign_fneg(half %a, half %b) nounwind {160; RV32I-LABEL: fcopysign_fneg:161; RV32I: # %bb.0:162; RV32I-NEXT: not a1, a1163; RV32I-NEXT: lui a2, 1048568164; RV32I-NEXT: slli a0, a0, 17165; RV32I-NEXT: and a1, a1, a2166; RV32I-NEXT: srli a0, a0, 17167; RV32I-NEXT: or a0, a0, a1168; RV32I-NEXT: ret169;170; RV32IZFH-LABEL: fcopysign_fneg:171; RV32IZFH: # %bb.0:172; RV32IZFH-NEXT: fmv.h.x fa5, a1173; RV32IZFH-NEXT: fmv.h.x fa4, a0174; RV32IZFH-NEXT: fsgnjn.h fa5, fa4, fa5175; RV32IZFH-NEXT: fmv.x.h a0, fa5176; RV32IZFH-NEXT: ret177;178; RV64I-LABEL: fcopysign_fneg:179; RV64I: # %bb.0:180; RV64I-NEXT: not a1, a1181; RV64I-NEXT: lui a2, 1048568182; RV64I-NEXT: slli a0, a0, 49183; RV64I-NEXT: and a1, a1, a2184; RV64I-NEXT: srli a0, a0, 49185; RV64I-NEXT: or a0, a0, a1186; RV64I-NEXT: ret187;188; RV64IZFH-LABEL: fcopysign_fneg:189; RV64IZFH: # %bb.0:190; RV64IZFH-NEXT: fmv.h.x fa5, a1191; RV64IZFH-NEXT: fmv.h.x fa4, a0192; RV64IZFH-NEXT: fsgnjn.h fa5, fa4, fa5193; RV64IZFH-NEXT: fmv.x.h a0, fa5194; RV64IZFH-NEXT: ret195;196; RV32IZHINX-LABEL: fcopysign_fneg:197; RV32IZHINX: # %bb.0:198; RV32IZHINX-NEXT: fsgnjn.h a0, a0, a1199; RV32IZHINX-NEXT: ret200;201; RV64IZHINX-LABEL: fcopysign_fneg:202; RV64IZHINX: # %bb.0:203; RV64IZHINX-NEXT: fsgnjn.h a0, a0, a1204; RV64IZHINX-NEXT: ret205;206; RV32IZFHMIN-LABEL: fcopysign_fneg:207; RV32IZFHMIN: # %bb.0:208; RV32IZFHMIN-NEXT: not a1, a1209; RV32IZFHMIN-NEXT: lui a2, 1048568210; RV32IZFHMIN-NEXT: slli a0, a0, 17211; RV32IZFHMIN-NEXT: and a1, a1, a2212; RV32IZFHMIN-NEXT: srli a0, a0, 17213; RV32IZFHMIN-NEXT: or a0, a0, a1214; RV32IZFHMIN-NEXT: ret215;216; RV64IZFHMIN-LABEL: fcopysign_fneg:217; RV64IZFHMIN: # %bb.0:218; RV64IZFHMIN-NEXT: not a1, a1219; RV64IZFHMIN-NEXT: lui a2, 1048568220; RV64IZFHMIN-NEXT: slli a0, a0, 49221; RV64IZFHMIN-NEXT: and a1, a1, a2222; RV64IZFHMIN-NEXT: srli a0, a0, 49223; RV64IZFHMIN-NEXT: or a0, a0, a1224; RV64IZFHMIN-NEXT: ret225;226; RV32IZHINXMIN-LABEL: fcopysign_fneg:227; RV32IZHINXMIN: # %bb.0:228; RV32IZHINXMIN-NEXT: # kill: def $x11_h killed $x11_h def $x11229; RV32IZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h def $x10230; RV32IZHINXMIN-NEXT: not a1, a1231; RV32IZHINXMIN-NEXT: lui a2, 1048568232; RV32IZHINXMIN-NEXT: slli a0, a0, 17233; RV32IZHINXMIN-NEXT: and a1, a1, a2234; RV32IZHINXMIN-NEXT: srli a0, a0, 17235; RV32IZHINXMIN-NEXT: or a0, a0, a1236; RV32IZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h killed $x10237; RV32IZHINXMIN-NEXT: ret238;239; RV64IZHINXMIN-LABEL: fcopysign_fneg:240; RV64IZHINXMIN: # %bb.0:241; RV64IZHINXMIN-NEXT: # kill: def $x11_h killed $x11_h def $x11242; RV64IZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h def $x10243; RV64IZHINXMIN-NEXT: not a1, a1244; RV64IZHINXMIN-NEXT: lui a2, 1048568245; RV64IZHINXMIN-NEXT: slli a0, a0, 49246; RV64IZHINXMIN-NEXT: and a1, a1, a2247; RV64IZHINXMIN-NEXT: srli a0, a0, 49248; RV64IZHINXMIN-NEXT: or a0, a0, a1249; RV64IZHINXMIN-NEXT: # kill: def $x10_h killed $x10_h killed $x10250; RV64IZHINXMIN-NEXT: ret251 %1 = fneg half %b252 %2 = call half @llvm.copysign.f16(half %a, half %1)253 ret half %2254}255