@@ -86,7 +86,8 @@ cl::opt<bool>
8686 DisableQFOptimizer (" disable-qfp-opt" , cl::init(false ),
8787 cl::desc(" Disable optimization of Qfloat operations." ));
8888
89- std::vector<unsigned short > QFPInst = {
89+ namespace {
90+ const std::vector<unsigned short > QFPInst = {
9091 Hexagon::V6_vadd_hf, Hexagon::V6_vadd_qf16,
9192 Hexagon::V6_vadd_qf16_mix, Hexagon::V6_vadd_qf32,
9293 Hexagon::V6_vadd_qf32_mix, Hexagon::V6_vadd_sf,
@@ -100,7 +101,7 @@ std::vector<unsigned short> QFPInst = {
100101 Hexagon::V6_vsub_qf32, Hexagon::V6_vsub_qf32_mix,
101102 Hexagon::V6_vsub_sf};
102103
103- std::map<unsigned short , unsigned short > QFPInstMap{
104+ const std::map<unsigned short , unsigned short > QFPInstMap{
104105 {Hexagon::V6_vadd_hf, Hexagon::V6_vadd_qf16_mix},
105106 {Hexagon::V6_vadd_qf16_mix, Hexagon::V6_vadd_qf16},
106107 {Hexagon::V6_vadd_sf, Hexagon::V6_vadd_qf32_mix},
@@ -114,6 +115,7 @@ std::map<unsigned short, unsigned short> QFPInstMap{
114115 {Hexagon::V6_vmpy_qf32_hf, Hexagon::V6_vmpy_qf32_mix_hf},
115116 {Hexagon::V6_vmpy_qf32_mix_hf, Hexagon::V6_vmpy_qf32_qf16},
116117 {Hexagon::V6_vmpy_qf32_sf, Hexagon::V6_vmpy_qf32}};
118+ }
117119
118120namespace llvm {
119121
@@ -164,11 +166,22 @@ bool HexagonQFPoptimizer::optimizeQfp(MachineInstr *MI,
164166
165167 unsigned Op0F = 0 ;
166168 unsigned Op1F = 0 ;
167- unsigned short InstTy = QFPInstMap[MI->getOpcode ()];
169+ auto It = QFPInstMap.find (MI->getOpcode ());
170+ if (It == QFPInstMap.end ())
171+ return false ;
172+ unsigned short InstTy = It->second ;
168173
169174 // Get the reaching defs of MI, DefMI1 and DefMI2
170- MachineInstr *DefMI1 = MRI->getVRegDef (MI->getOperand (1 ).getReg ());
171- MachineInstr *DefMI2 = MRI->getVRegDef (MI->getOperand (2 ).getReg ());
175+ MachineInstr *DefMI1 = nullptr ;
176+ MachineInstr *DefMI2 = nullptr ;
177+
178+ if (MI->getOperand (1 ).isReg ())
179+ DefMI1 = MRI->getVRegDef (MI->getOperand (1 ).getReg ());
180+ if (MI->getOperand (2 ).isReg ())
181+ DefMI2 = MRI->getVRegDef (MI->getOperand (2 ).getReg ());
182+ if (!DefMI1 || !DefMI2)
183+ return false ;
184+
172185 MachineOperand &Res = MI->getOperand (0 );
173186 MachineInstr *Inst1 = nullptr ;
174187 MachineInstr *Inst2 = nullptr ;
@@ -188,19 +201,22 @@ bool HexagonQFPoptimizer::optimizeQfp(MachineInstr *MI,
188201 unsigned Def2OP = DefMI2->getOpcode ();
189202
190203 MachineInstrBuilder MIB;
191- // Check if the both the reaching defs of MI and qf to sf/hf conversions
204+ // Case 1: Both reaching defs of MI are qf to sf/hf conversions
192205 if ((Def1OP == Hexagon::V6_vconv_sf_qf32 &&
193206 Def2OP == Hexagon::V6_vconv_sf_qf32) ||
194207 (Def1OP == Hexagon::V6_vconv_hf_qf16 &&
195208 Def2OP == Hexagon::V6_vconv_hf_qf16)) {
196209
197210 // If the reaching defs of DefMI are W register type, we return
198- if ((Inst1 && MRI->getRegClass (Inst1->getOperand (0 ).getReg ()) ==
199- &Hexagon::HvxWRRegClass) ||
200- (Inst2 && MRI->getRegClass (Inst2->getOperand (0 ).getReg ()) ==
201- &Hexagon::HvxWRRegClass))
211+ if ((Inst1 && Inst1->getNumOperands () > 0 &&
212+ Inst1->getOperand (0 ).isReg () &&
213+ MRI->getRegClass (Inst1->getOperand (0 ).getReg ()) == &Hexagon::HvxWRRegClass) ||
214+ (Inst2 && Inst2->getNumOperands () > 0 &&
215+ Inst2->getOperand (0 ).isReg () &&
216+ MRI->getRegClass (Inst2->getOperand (0 ).getReg ()) == &Hexagon::HvxWRRegClass))
202217 return false ;
203218
219+
204220 // Analyze the use operands of the conversion to get their KILL status
205221 MachineOperand &Src1 = DefMI1->getOperand (1 );
206222 MachineOperand &Src2 = DefMI2->getOperand (1 );
@@ -211,16 +227,23 @@ bool HexagonQFPoptimizer::optimizeQfp(MachineInstr *MI,
211227 Op1F = getKillRegState (Src2.isKill ());
212228 Src2.setIsKill (false );
213229
214- if (MI->getOpcode () != Hexagon::V6_vmpy_qf32_sf)
215- InstTy = QFPInstMap[QFPInstMap[MI->getOpcode ()]];
230+ if (MI->getOpcode () != Hexagon::V6_vmpy_qf32_sf) {
231+ auto OuterIt = QFPInstMap.find (MI->getOpcode ());
232+ if (OuterIt == QFPInstMap.end ())
233+ return false ;
234+ auto InnerIt = QFPInstMap.find (OuterIt->second );
235+ if (InnerIt == QFPInstMap.end ())
236+ return false ;
237+ InstTy = InnerIt->second ;
238+ }
216239
217240 MIB = BuildMI (*MBB, MI, MI->getDebugLoc (), HII->get (InstTy), Res.getReg ())
218241 .addReg (Src1.getReg (), Op0F, Src1.getSubReg ())
219242 .addReg (Src2.getReg (), Op1F, Src2.getSubReg ());
220243 LLVM_DEBUG (dbgs () << " \n [Inserting]: " ; MIB.getInstr ()->dump ());
221244 return true ;
222245
223- // Check if left operand's reaching def is a conversion to sf/hf
246+ // Case 2: Left operand is conversion to sf/hf
224247 } else if (((Def1OP == Hexagon::V6_vconv_sf_qf32 &&
225248 Def2OP != Hexagon::V6_vconv_sf_qf32) ||
226249 (Def1OP == Hexagon::V6_vconv_hf_qf16 &&
@@ -244,7 +267,7 @@ bool HexagonQFPoptimizer::optimizeQfp(MachineInstr *MI,
244267 LLVM_DEBUG (dbgs () << " \n [Inserting]: " ; MIB.getInstr ()->dump ());
245268 return true ;
246269
247- // Check if right operand's reaching def is a conversion tp sf/hf
270+ // Case 2: Left operand is conversion to sf/hf
248271 } else if (((Def1OP != Hexagon::V6_vconv_sf_qf32 &&
249272 Def2OP == Hexagon::V6_vconv_sf_qf32) ||
250273 (Def1OP != Hexagon::V6_vconv_hf_qf16 &&
0 commit comments