127#define HEXAGON_XQFLOAT_GENERATOR "XQFloat Generator pass"
149#define DEBUG_TYPE "hexagon-xqf-gen"
157 cl::desc(
"Enable XQFloat generations"));
161 Hexagon::V6_vadd_sf, Hexagon::V6_vadd_qf32, Hexagon::V6_vadd_qf32_mix,
164 Hexagon::V6_vsub_qf32, Hexagon::V6_vsub_qf32_mix, Hexagon::V6_vsub_sf,
165 Hexagon::V6_vsub_sf_mix};
170 Hexagon::V6_vadd_hf, Hexagon::V6_vadd_qf16, Hexagon::V6_vadd_qf16_mix,
173 Hexagon::V6_vsub_hf, Hexagon::V6_vsub_qf16, Hexagon::V6_vsub_qf16_mix,
174 Hexagon::V6_vsub_hf_mix};
178 Hexagon::V6_vmpy_qf32, Hexagon::V6_vmpy_qf32_qf16, Hexagon::V6_vmpy_qf32_hf,
179 Hexagon::V6_vmpy_qf32_sf, Hexagon::V6_vmpy_qf32_mix_hf};
181static constexpr unsigned XQFPMult16[] = {Hexagon::V6_vmpy_qf16,
182 Hexagon::V6_vmpy_qf16_hf,
183 Hexagon::V6_vmpy_qf16_mix_hf};
195 HexagonXQFloatGenerator() : MachineFunctionPass(ID) {}
197 bool runOnMachineFunction(MachineFunction &MF)
override;
201 void getAnalysisUsage(AnalysisUsage &AU)
const override {
207 bool HandleStrictIEEE(MachineFunction &);
208 bool HandleCompliantIEEE(MachineFunction &);
209 bool HandleLossySubnormals(MachineFunction &);
210 bool HandleLossyLegacy(MachineFunction &);
225 bool normalizeMultiplicationInputF32(MachineInstr &,
Register &,
Register &,
235 void createPrologInstructions(MachineInstr &,
Register &);
241 bool convertIfInputToNonHVX(MachineInstr &,
bool);
248 const HexagonSubtarget *HST =
nullptr;
249 const HexagonInstrInfo *HII =
nullptr;
250 MachineRegisterInfo *MRI =
nullptr;
260char HexagonXQFloatGenerator::ID = 0;
268 return new HexagonXQFloatGenerator();
272bool HexagonXQFloatGenerator::checkIfInputFromAdder32(
Register Reg) {
278 if (
Def->getOpcode() == TargetOpcode::COPY) {
281 return checkIfInputFromAdder32(SrcReg);
283 }
else if (
Def->getOpcode() == TargetOpcode::REG_SEQUENCE) {
288 isTrue = checkIfInputFromAdder32(SrcReg1);
290 isTrue |= checkIfInputFromAdder32(SrcReg2);
297bool HexagonXQFloatGenerator::checkIfInputFromAdder16(
Register Reg) {
303 if (
Def->getOpcode() == TargetOpcode::COPY) {
306 return checkIfInputFromAdder16(SrcReg);
313bool HexagonXQFloatGenerator::checkIfInputFromMult32(
Register Reg) {
319 if (
Def->getOpcode() == TargetOpcode::COPY) {
322 return checkIfInputFromMult32(SrcReg);
324 }
else if (
Def->getOpcode() == TargetOpcode::REG_SEQUENCE) {
329 isTrue |= checkIfInputFromMult32(SrcReg1);
331 isTrue |= checkIfInputFromMult32(SrcReg2);
338bool HexagonXQFloatGenerator::checkIfInputFromMult16(
Register Reg) {
344 if (
Def->getOpcode() == TargetOpcode::COPY) {
347 return checkIfInputFromMult16(SrcReg);
354void HexagonXQFloatGenerator::createConvertInstr(MachineInstr *
UseMI,
369bool HexagonXQFloatGenerator::convertIfInputToNonHVX(MachineInstr &
MI,
378 MachineInstr *
UseMI = MO.getParent();
394 return convertIfInputToNonHVX(*
UseMI,
true);
396 createConvertInstr(
UseMI, NewR, Dest,
true);
404 return convertIfInputToNonHVX(*
UseMI,
false);
406 createConvertInstr(
UseMI, NewR, Dest,
false);
419void HexagonXQFloatGenerator::generateQF16FromQF32(MachineInstr &
MI,
423 MachineBasicBlock &
MBB = *
MI.getParent();
427 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vconv_hf_qf32), convertReg)
438void HexagonXQFloatGenerator::widenMultiplyInputHF(MachineInstr &
MI,
443 MachineBasicBlock &
MBB = *
MI.getParent();
446 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_hf), output_mpy)
449 generateQF16FromQF32(
MI, Dest, output_mpy);
453bool HexagonXQFloatGenerator::widenMultiplicationInputF16(MachineInstr &
MI,
458 bool firstconvert =
false, secondconvert =
false;
459 MachineBasicBlock &
MBB = *
MI.getParent();
463 if (checkIfInputFromAdder16(Reg1))
466 if (twoOps && checkIfInputFromAdder16(Reg2))
467 secondconvert =
true;
472 if (firstconvert || secondconvert) {
474 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_qf16), widenReg)
483 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_mix_hf), widenReg)
492 generateQF16FromQF32(
MI, Dest, widenReg);
499bool HexagonXQFloatGenerator::widenMultiplicationInputF16Rt(MachineInstr &
MI,
505 if (!checkIfInputFromAdder16(Reg1)) {
507 if (!checkIfInputFromMult16(Reg1))
513 MachineBasicBlock &
MBB = *
MI.getParent();
523 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_hf), widenReg)
527 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_mix_hf), widenReg)
533 generateQF16FromQF32(
MI, Dest, widenReg);
542bool HexagonXQFloatGenerator::convertAddOpToIEEE32(
544 bool isAdd,
bool isFirstOpQf,
bool isSecOpQf) {
548 bool firstconvert =
false, secondconvert =
false;
549 MachineBasicBlock &
MBB = *
MI.getParent();
556 if (checkIfInputFromAdder32(Reg1) || checkIfInputFromMult32(Reg1)) {
568 if (checkIfInputFromAdder32(Reg2) || checkIfInputFromMult32(Reg2)) {
572 secondconvert =
true;
579 if (isFirstOpQf && isSecOpQf) {
580 if (firstconvert && secondconvert) {
582 HII->get(isAdd ? Hexagon::V6_vadd_sf : Hexagon::V6_vsub_sf), Dest)
585 }
else if (firstconvert) {
606 }
else if (secondconvert) {
608 HII->get(isAdd ? Hexagon::V6_vadd_qf32_mix
609 : Hexagon::V6_vsub_qf32_mix),
617 }
else if (isFirstOpQf) {
620 HII->get(isAdd ? Hexagon::V6_vadd_sf : Hexagon::V6_vsub_sf), Dest)
626 }
else if (isSecOpQf) {
629 HII->get(isAdd ? Hexagon::V6_vadd_sf : Hexagon::V6_vsub_sf), Dest)
644bool HexagonXQFloatGenerator::convertAddOpToIEEE16(
646 bool isAdd,
bool isFirstOpQf,
bool isSecOpQf) {
648 MachineBasicBlock &
MBB = *
MI.getParent();
652 bool firstconvert =
false, secondconvert =
false;
657 if (checkIfInputFromAdder16(Reg1) || checkIfInputFromMult16(Reg1)) {
667 if (checkIfInputFromAdder16(Reg2) || checkIfInputFromMult16(Reg2)) {
671 secondconvert =
true;
678 if (isFirstOpQf && isSecOpQf) {
679 if (firstconvert && secondconvert) {
681 HII->get(isAdd ? Hexagon::V6_vadd_hf : Hexagon::V6_vsub_hf), Dest)
684 }
else if (firstconvert) {
705 }
else if (secondconvert) {
707 HII->get(isAdd ? Hexagon::V6_vadd_qf16_mix
708 : Hexagon::V6_vsub_qf16_mix),
716 }
else if (isFirstOpQf) {
719 HII->get(isAdd ? Hexagon::V6_vadd_hf : Hexagon::V6_vsub_hf), Dest)
725 }
else if (isSecOpQf) {
728 HII->get(isAdd ? Hexagon::V6_vadd_hf : Hexagon::V6_vsub_hf), Dest)
743void HexagonXQFloatGenerator::createPrologInstructions(MachineInstr &
MI,
746 MachineBasicBlock &
MBB = *
MI.getParent();
764bool HexagonXQFloatGenerator::V81normalizeMultF32(
766 bool firstconvert,
bool secondconvert,
bool strictieee) {
767 MachineBasicBlock &
MBB = *
MI.getParent();
772 strictieee ? Hexagon::V6_vconv_qf32_sf : Hexagon::V6_vconv_qf32_qf32;
775 if (firstconvert && secondconvert) {
786 else if (firstconvert) {
794 else if (secondconvert) {
808void HexagonXQFloatGenerator::normalizeMultiplicationInputSF(
810 Register &R_mpy,
bool &PrologCreated) {
812 MachineBasicBlock &
MBB = *
MI.getParent();
820 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vconv_qf32_sf), input_mpy1)
822 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vconv_qf32_sf), input_mpy2)
831 if (!PrologCreated) {
832 createPrologInstructions(
MI, R_mpy);
833 PrologCreated =
true;
839 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32_mix), input_mpy1)
842 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32_mix), input_mpy2)
852bool HexagonXQFloatGenerator::convertNormalizeMultOp32(
854 Register &R_mpy,
bool &PrologCreated) {
857 bool firstconvert =
false, secondconvert =
false;
858 MachineBasicBlock &
MBB = *
MI.getParent();
863 if (checkIfInputFromAdder32(Reg1) || checkIfInputFromMult32(Reg1)) {
869 if (checkIfInputFromAdder32(Reg2) || checkIfInputFromMult32(Reg2)) {
872 secondconvert =
true;
876 if (firstconvert && secondconvert)
877 return V81normalizeMultF32(
MI, VR1, VR2, Dest,
true,
true,
true);
878 else if (firstconvert)
879 return V81normalizeMultF32(
MI, VR1, Reg2, Dest,
true,
false,
true);
880 else if (secondconvert)
881 return V81normalizeMultF32(
MI, Reg1, VR2, Dest,
false,
true,
true);
887 if (!PrologCreated && (firstconvert || secondconvert)) {
888 createPrologInstructions(
MI, R_mpy);
889 PrologCreated =
true;
895 if (firstconvert && secondconvert) {
899 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32_mix), input_mpy1)
902 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32_mix), input_mpy2)
909 }
else if (firstconvert) {
912 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32_mix), input_mpy1)
919 }
else if (secondconvert) {
922 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32_mix), input_mpy2)
938bool HexagonXQFloatGenerator::convertWidenMultOp16(MachineInstr &
MI,
945 bool firstconvert =
false,
946 secondconvert =
false;
947 MachineBasicBlock &
MBB = *
MI.getParent();
952 if (checkIfInputFromAdder16(Reg1) || checkIfInputFromMult16(Reg1)) {
959 if (checkIfInputFromAdder16(Reg2) || checkIfInputFromMult16(Reg2)) {
963 secondconvert =
true;
969 if (firstconvert && secondconvert) {
971 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_hf), output_mpy)
975 }
else if (firstconvert) {
977 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_mix_hf), output_mpy)
980 }
else if (secondconvert) {
982 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_mix_hf), output_mpy)
992 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_hf), output_mpy)
1000 generateQF16FromQF32(
MI, Dest, output_mpy);
1007bool HexagonXQFloatGenerator::convertWidenMultOp32(MachineInstr &
MI,
1013 bool firstconvert =
false,
1014 secondconvert =
false;
1015 MachineBasicBlock &
MBB = *
MI.getParent();
1020 if (checkIfInputFromAdder16(Reg1) || checkIfInputFromMult16(Reg1)) {
1023 firstconvert =
true;
1027 if (checkIfInputFromAdder16(Reg2) || checkIfInputFromMult16(Reg2)) {
1031 secondconvert =
true;
1037 if (firstconvert && secondconvert) {
1042 }
else if (firstconvert) {
1043 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_mix_hf), Dest)
1046 }
else if (secondconvert) {
1047 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vmpy_qf32_mix_hf), Dest)
1066bool HexagonXQFloatGenerator::normalizeMultiplicationInputF32(
1068 Register &R_mpy,
bool &PrologCreated) {
1069 bool firstconvert =
false, secondconvert =
false;
1070 MachineBasicBlock &
MBB = *
MI.getParent();
1074 if (checkIfInputFromAdder32(Reg1))
1075 firstconvert =
true;
1076 if (checkIfInputFromAdder32(Reg2))
1077 secondconvert =
true;
1081 return V81normalizeMultF32(
MI, Reg1, Reg2, Dest, firstconvert,
1082 secondconvert,
false);
1085 if ((!PrologCreated && (firstconvert || secondconvert))) {
1086 createPrologInstructions(
MI, R_mpy);
1087 PrologCreated =
true;
1093 if (firstconvert && secondconvert) {
1097 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32), input_mpy1)
1100 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32), input_mpy2)
1107 }
else if (firstconvert) {
1110 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32), input_mpy1)
1117 }
else if (secondconvert) {
1120 BuildMI(
MBB,
MI,
DL, HII->get(Hexagon::V6_vadd_qf32), input_mpy2)
1134bool HexagonXQFloatGenerator::deleteList() {
1135 if (OriginalMI.empty())
1138 for (MachineInstr *origMI : OriginalMI) {
1141 origMI->eraseFromParent();
1149bool HexagonXQFloatGenerator::HandleLossySubnormals(MachineFunction &MF) {
1152 for (
auto &
MBB : MF) {
1153 bool PrologCreated =
false;
1154 for (
auto &
MI :
MBB) {
1159 if (
MI.getNumOperands() != 3 ||
MI.isDebugInstr())
1161 auto Op1 =
MI.getOperand(1);
1164 auto Op2 =
MI.getOperand(2);
1167 auto Op0 =
MI.getOperand(0);
1178 switch (
MI.getOpcode()) {
1182 case Hexagon::V6_vmpy_qf32:
1183 if (normalizeMultiplicationInputF32(
MI, Reg1, Reg2, Dest, R_mpy,
1185 OriginalMI.push_back(&
MI);
1186 Changed |= convertIfInputToNonHVX(
MI,
true);
1192 case Hexagon::V6_vmpy_qf16:
1193 if (widenMultiplicationInputF16(
MI, Reg1, Reg2, Dest,
true))
1194 OriginalMI.push_back(&
MI);
1195 Changed |= convertIfInputToNonHVX(
MI,
false);
1202 case Hexagon::V6_vmpy_rt_qf16:
1203 if (widenMultiplicationInputF16Rt(
MI, Reg1, Reg2, Dest))
1204 OriginalMI.push_back(&
MI);
1205 Changed |= convertIfInputToNonHVX(
MI,
false);
1211 case Hexagon::V6_vmpy_qf16_mix_hf:
1212 if (widenMultiplicationInputF16(
MI, Reg1, Reg2, Dest,
false))
1213 OriginalMI.push_back(&
MI);
1214 Changed |= convertIfInputToNonHVX(
MI,
false);
1219 case Hexagon::V6_vadd_sf:
1220 case Hexagon::V6_vadd_qf32:
1221 case Hexagon::V6_vadd_qf32_mix:
1222 case Hexagon::V6_vsub_sf:
1223 case Hexagon::V6_vsub_qf32:
1224 case Hexagon::V6_vsub_qf32_mix:
1225 case Hexagon::V6_vsub_sf_mix:
1226 case Hexagon::V6_vmpy_qf32_qf16:
1227 case Hexagon::V6_vmpy_qf32_hf:
1228 case Hexagon::V6_vmpy_qf32_mix_hf:
1229 case Hexagon::V6_vmpy_rt_sf:
1230 case Hexagon::V6_vmpy_qf32_sf:
1231 Changed |= convertIfInputToNonHVX(
MI,
true);
1236 case Hexagon::V6_vadd_hf:
1237 case Hexagon::V6_vsub_hf:
1238 case Hexagon::V6_vadd_qf16:
1239 case Hexagon::V6_vsub_qf16:
1240 case Hexagon::V6_vadd_qf16_mix:
1241 case Hexagon::V6_vsub_qf16_mix:
1242 case Hexagon::V6_vsub_hf_mix:
1243 case Hexagon::V6_vmpy_qf16_hf:
1244 case Hexagon::V6_vmpy_rt_hf:
1245 Changed |= convertIfInputToNonHVX(
MI,
false);
1252 if (OriginalMI.empty() || !
Changed)
1258bool HexagonXQFloatGenerator::HandleCompliantIEEE(MachineFunction &MF) {
1261 for (
auto &
MBB : MF) {
1262 bool PrologCreated =
false;
1263 for (
auto &
MI :
MBB) {
1268 if (
MI.getNumOperands() != 3 ||
MI.isDebugInstr())
1271 auto Op1 =
MI.getOperand(1);
1274 auto Op2 =
MI.getOperand(2);
1277 auto Op0 =
MI.getOperand(0);
1289 switch (
MI.getOpcode()) {
1296 case Hexagon::V6_vmpy_rt_sf:
1298 BuildMI(
MBB,
MI,
MI.getDebugLoc(), HII->get(Hexagon::V6_lvsplatw),
1301 normalizeMultiplicationInputSF(
MI, Reg1, VRtSplat, Dest, R_mpy,
1303 OriginalMI.push_back(&
MI);
1304 Changed |= convertIfInputToNonHVX(
MI,
true);
1309 case Hexagon::V6_vmpy_qf32_sf:
1310 normalizeMultiplicationInputSF(
MI, Reg1, Reg2, Dest, R_mpy,
1312 OriginalMI.push_back(&
MI);
1313 Changed |= convertIfInputToNonHVX(
MI,
true);
1319 case Hexagon::V6_vmpy_qf32:
1320 if (normalizeMultiplicationInputF32(
MI, Reg1, Reg2, Dest, R_mpy,
1322 OriginalMI.push_back(&
MI);
1323 Changed |= convertIfInputToNonHVX(
MI,
true);
1328 case Hexagon::V6_vmpy_rt_hf:
1330 BuildMI(
MBB,
MI,
MI.getDebugLoc(), HII->get(Hexagon::V6_lvsplatw),
1333 widenMultiplyInputHF(
MI, Reg1, VRtSplat, Dest);
1334 OriginalMI.push_back(&
MI);
1335 Changed |= convertIfInputToNonHVX(
MI,
false);
1340 case Hexagon::V6_vmpy_qf16_hf:
1341 widenMultiplyInputHF(
MI, Reg1, Reg2, Dest);
1342 OriginalMI.push_back(&
MI);
1343 Changed |= convertIfInputToNonHVX(
MI,
false);
1349 case Hexagon::V6_vmpy_qf16:
1350 if (widenMultiplicationInputF16(
MI, Reg1, Reg2, Dest,
true))
1351 OriginalMI.push_back(&
MI);
1352 Changed |= convertIfInputToNonHVX(
MI,
false);
1359 case Hexagon::V6_vmpy_rt_qf16:
1360 if (widenMultiplicationInputF16Rt(
MI, Reg1, Reg2, Dest))
1361 OriginalMI.push_back(&
MI);
1362 Changed |= convertIfInputToNonHVX(
MI,
false);
1368 case Hexagon::V6_vmpy_qf16_mix_hf:
1369 if (widenMultiplicationInputF16(
MI, Reg1, Reg2, Dest,
false))
1370 OriginalMI.push_back(&
MI);
1371 Changed |= convertIfInputToNonHVX(
MI,
false);
1377 case Hexagon::V6_vadd_sf:
1378 case Hexagon::V6_vadd_qf32:
1379 case Hexagon::V6_vadd_qf32_mix:
1380 case Hexagon::V6_vsub_sf:
1381 case Hexagon::V6_vsub_qf32:
1382 case Hexagon::V6_vsub_qf32_mix:
1383 case Hexagon::V6_vsub_sf_mix:
1384 case Hexagon::V6_vmpy_qf32_qf16:
1385 case Hexagon::V6_vmpy_qf32_hf:
1386 case Hexagon::V6_vmpy_qf32_mix_hf:
1387 Changed |= convertIfInputToNonHVX(
MI,
true);
1389 case Hexagon::V6_vadd_hf:
1390 case Hexagon::V6_vsub_hf:
1391 case Hexagon::V6_vadd_qf16:
1392 case Hexagon::V6_vsub_qf16:
1393 case Hexagon::V6_vadd_qf16_mix:
1394 case Hexagon::V6_vsub_qf16_mix:
1395 case Hexagon::V6_vsub_hf_mix:
1396 Changed |= convertIfInputToNonHVX(
MI,
false);
1403 if (OriginalMI.empty() || !
Changed)
1409bool HexagonXQFloatGenerator::HandleStrictIEEE(MachineFunction &MF) {
1413 for (
auto &
MBB : MF) {
1414 bool PrologCreated =
false;
1415 for (
auto &
MI :
MBB) {
1420 if (
MI.getNumOperands() != 3 ||
MI.isDebugInstr())
1423 auto Op1 =
MI.getOperand(1);
1426 auto Op2 =
MI.getOperand(2);
1429 auto Op0 =
MI.getOperand(0);
1441 switch (
MI.getOpcode()) {
1446 case Hexagon::V6_vadd_qf32:
1447 if (convertAddOpToIEEE32(
MI, Reg1, Reg2, Dest,
true,
true,
true))
1448 OriginalMI.push_back(&
MI);
1449 Changed |= convertIfInputToNonHVX(
MI,
true);
1452 case Hexagon::V6_vsub_qf32:
1453 if (convertAddOpToIEEE32(
MI, Reg1, Reg2, Dest,
false,
true,
true))
1454 OriginalMI.push_back(&
MI);
1455 Changed |= convertIfInputToNonHVX(
MI,
true);
1460 case Hexagon::V6_vadd_qf32_mix:
1461 if (convertAddOpToIEEE32(
MI, Reg1, Reg2, Dest,
true,
true,
false))
1462 OriginalMI.push_back(&
MI);
1463 Changed |= convertIfInputToNonHVX(
MI,
true);
1466 case Hexagon::V6_vsub_qf32_mix:
1467 if (convertAddOpToIEEE32(
MI, Reg1, Reg2, Dest,
false,
true,
false))
1468 OriginalMI.push_back(&
MI);
1469 Changed |= convertIfInputToNonHVX(
MI,
true);
1472 case Hexagon::V6_vsub_sf_mix:
1473 if (convertAddOpToIEEE32(
MI, Reg1, Reg2, Dest,
false,
false,
true))
1474 OriginalMI.push_back(&
MI);
1475 Changed |= convertIfInputToNonHVX(
MI,
true);
1482 case Hexagon::V6_vadd_qf16:
1483 if (convertAddOpToIEEE16(
MI, Reg1, Reg2, Dest,
true,
true,
true))
1484 OriginalMI.push_back(&
MI);
1485 Changed |= convertIfInputToNonHVX(
MI,
false);
1488 case Hexagon::V6_vsub_qf16:
1489 if (convertAddOpToIEEE16(
MI, Reg1, Reg2, Dest,
false,
true,
true))
1490 OriginalMI.push_back(&
MI);
1491 Changed |= convertIfInputToNonHVX(
MI,
false);
1496 case Hexagon::V6_vadd_qf16_mix:
1497 if (convertAddOpToIEEE16(
MI, Reg1, Reg2, Dest,
true,
true,
false))
1498 OriginalMI.push_back(&
MI);
1499 Changed |= convertIfInputToNonHVX(
MI,
false);
1502 case Hexagon::V6_vsub_qf16_mix:
1503 if (convertAddOpToIEEE16(
MI, Reg1, Reg2, Dest,
false,
true,
false))
1504 OriginalMI.push_back(&
MI);
1505 Changed |= convertIfInputToNonHVX(
MI,
false);
1508 case Hexagon::V6_vsub_hf_mix:
1509 if (convertAddOpToIEEE16(
MI, Reg1, Reg2, Dest,
false,
false,
true))
1510 OriginalMI.push_back(&
MI);
1511 Changed |= convertIfInputToNonHVX(
MI,
false);
1519 case Hexagon::V6_vmpy_rt_sf:
1521 BuildMI(
MBB,
MI,
MI.getDebugLoc(), HII->get(Hexagon::V6_lvsplatw),
1524 normalizeMultiplicationInputSF(
MI, Reg1, VRtSplat, Dest, R_mpy,
1526 OriginalMI.push_back(&
MI);
1527 Changed |= convertIfInputToNonHVX(
MI,
true);
1532 case Hexagon::V6_vmpy_qf32_sf:
1533 normalizeMultiplicationInputSF(
MI, Reg1, Reg2, Dest, R_mpy,
1535 Changed |= convertIfInputToNonHVX(
MI,
true);
1536 OriginalMI.push_back(&
MI);
1542 case Hexagon::V6_vmpy_qf32:
1543 if (convertNormalizeMultOp32(
MI, Reg1, Reg2, Dest, R_mpy,
1545 OriginalMI.push_back(&
MI);
1546 Changed |= convertIfInputToNonHVX(
MI,
true);
1554 case Hexagon::V6_vmpy_qf16:
1555 if (convertWidenMultOp16(
MI, Reg1, Reg2, Dest,
true))
1556 OriginalMI.push_back(&
MI);
1557 Changed |= convertIfInputToNonHVX(
MI,
false);
1564 case Hexagon::V6_vmpy_qf32_qf16:
1565 if (convertWidenMultOp32(
MI, Reg1, Reg2, Dest,
true))
1566 OriginalMI.push_back(&
MI);
1567 Changed |= convertIfInputToNonHVX(
MI,
true);
1572 case Hexagon::V6_vmpy_rt_hf:
1574 BuildMI(
MBB,
MI,
MI.getDebugLoc(), HII->get(Hexagon::V6_lvsplatw),
1577 widenMultiplyInputHF(
MI, Reg1, VRtSplat, Dest);
1578 OriginalMI.push_back(&
MI);
1579 Changed |= convertIfInputToNonHVX(
MI,
false);
1584 case Hexagon::V6_vmpy_qf16_hf:
1585 widenMultiplyInputHF(
MI, Reg1, Reg2, Dest);
1586 OriginalMI.push_back(&
MI);
1587 Changed |= convertIfInputToNonHVX(
MI,
false);
1594 case Hexagon::V6_vmpy_rt_qf16:
1595 if (widenMultiplicationInputF16Rt(
MI, Reg1, Reg2, Dest))
1596 OriginalMI.push_back(&
MI);
1597 Changed |= convertIfInputToNonHVX(
MI,
false);
1605 case Hexagon::V6_vmpy_qf16_mix_hf:
1606 if (convertWidenMultOp16(
MI, Reg1, Reg2, Dest,
false))
1607 OriginalMI.push_back(&
MI);
1608 Changed |= convertIfInputToNonHVX(
MI,
false);
1615 case Hexagon::V6_vmpy_qf32_mix_hf:
1616 if (convertWidenMultOp32(
MI, Reg1, Reg2, Dest,
false))
1617 OriginalMI.push_back(&
MI);
1618 Changed |= convertIfInputToNonHVX(
MI,
true);
1623 case Hexagon::V6_vadd_sf:
1624 case Hexagon::V6_vsub_sf:
1625 Changed |= convertIfInputToNonHVX(
MI,
true);
1627 case Hexagon::V6_vadd_hf:
1628 case Hexagon::V6_vsub_hf:
1629 Changed |= convertIfInputToNonHVX(
MI,
false);
1636 if (OriginalMI.empty() || !
Changed)
1642bool HexagonXQFloatGenerator::HandleLossyLegacy(MachineFunction &MF) {
1646bool HexagonXQFloatGenerator::runOnMachineFunction(MachineFunction &MF) {
1656 case QFloatMode::StrictIEEE:
1657 LLVM_DEBUG(
dbgs() <<
"\nGenerating code for STRICT-IEEE mode.\n");
1658 Changed = HandleStrictIEEE(MF);
1660 case QFloatMode::IEEE:
1662 Changed = HandleCompliantIEEE(MF);
1664 case QFloatMode::Lossy:
1666 Changed = HandleLossySubnormals(MF);
1668 case QFloatMode::Legacy:
1670 Changed = HandleLossyLegacy(MF);
1676 for (MachineInstr *origMI : OriginalMI) {
1678 origMI->eraseFromParent();
MachineInstrBuilder & UseMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
cl::opt< QFloatMode > QFloatModeValue
static constexpr unsigned XQFPMult32[]
cl::opt< bool > EnableHVXXQFloat("enable-xqf-gen", cl::init(false), cl::desc("Enable XQFloat generations"))
static constexpr unsigned XQFPAdd16[]
static constexpr unsigned XQFPAdd32[]
#define HEXAGON_XQFLOAT_GENERATOR
static constexpr unsigned XQFPMult16[]
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
FunctionPass class - This class is used to implement most global optimizations.
bool usesQFOperand(MachineInstr *MI, unsigned Index=0) const
const HexagonInstrInfo * getInstrInfo() const override
bool useHVXV81Ops() const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
use_iterator use_begin(Register RegNo) const
static use_iterator use_end()
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
initializer< Ty > init(const Ty &Val)
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createHexagonXQFloatGenerator()
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
void initializeHexagonXQFloatGeneratorPass(PassRegistry &)
DWARFExpression::Operation Op
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.