@@ -33,6 +33,8 @@ let Namespace = "Test" in {
3333
3434def Inst0 : TestInst<0>;
3535def Inst1 : TestInst<1>;
36+ let isCommutable = true in
37+ def Inst2 : TestInst<2>;
3638
3739def BothFusionPredicate: BothFusionPredicateWithMCInstPredicate<CheckRegOperand<0, X0>>;
3840def TestBothFusionPredicate: Fusion<"test-both-fusion-predicate", "HasBothFusionPredicate",
@@ -55,13 +57,19 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta
5557 CheckRegOperand<0, X0>
5658 ]>>;
5759
60+ def TestSingleFusion: SingleFusion<"test-single-fusion", "HasTestSingleFusion",
61+ "Test SingleFusion",
62+ Inst0, Inst2,
63+ secondInstPred=CheckRegOperand<0, X0>>;
64+
5865// CHECK-PREDICATOR: #ifdef GET_Test_MACRO_FUSION_PRED_DECL
5966// CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_DECL
6067// CHECK-PREDICATOR-EMPTY:
6168// CHECK-PREDICATOR-NEXT: namespace llvm {
6269// CHECK-PREDICATOR-NEXT: bool isTestBothFusionPredicate(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
6370// CHECK-PREDICATOR-NEXT: bool isTestCommutableFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
6471// CHECK-PREDICATOR-NEXT: bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
72+ // CHECK-PREDICATOR-NEXT: bool isTestSingleFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
6573// CHECK-PREDICATOR-NEXT: } // end namespace llvm
6674// CHECK-PREDICATOR-EMPTY:
6775// CHECK-PREDICATOR-NEXT: #endif
@@ -172,6 +180,57 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta
172180// CHECK-PREDICATOR-NEXT: return false;
173181// CHECK-PREDICATOR-NEXT: return true;
174182// CHECK-PREDICATOR-NEXT: }
183+ // CHECK-PREDICATOR-NEXT: bool isTestSingleFusion(
184+ // CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII,
185+ // CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI,
186+ // CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI,
187+ // CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) {
188+ // CHECK-PREDICATOR-NEXT: auto &MRI = SecondMI.getMF()->getRegInfo();
189+ // CHECK-PREDICATOR-NEXT: {
190+ // CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI;
191+ // CHECK-PREDICATOR-NEXT: if (!(
192+ // CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst2 )
193+ // CHECK-PREDICATOR-NEXT: && MI->getOperand(0).getReg() == Test::X0
194+ // CHECK-PREDICATOR-NEXT: ))
195+ // CHECK-PREDICATOR-NEXT: return false;
196+ // CHECK-PREDICATOR-NEXT: }
197+ // CHECK-PREDICATOR-NEXT: if (!FirstMI)
198+ // CHECK-PREDICATOR-NEXT: return true;
199+ // CHECK-PREDICATOR-NEXT: {
200+ // CHECK-PREDICATOR-NEXT: const MachineInstr *MI = FirstMI;
201+ // CHECK-PREDICATOR-NEXT: if (!(
202+ // CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst0 )
203+ // CHECK-PREDICATOR-NEXT: && true
204+ // CHECK-PREDICATOR-NEXT: ))
205+ // CHECK-PREDICATOR-NEXT: return false;
206+ // CHECK-PREDICATOR-NEXT: }
207+ // CHECK-PREDICATOR-NEXT: if (!SecondMI.getOperand(0).getReg().isVirtual()) {
208+ // CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) {
209+ // CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable())
210+ // CHECK-PREDICATOR-NEXT: return false;
211+ // CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
212+ // CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
213+ // CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
214+ // CHECK-PREDICATOR-NEXT: return false;
215+ // CHECK-PREDICATOR-NEXT: }
216+ // CHECK-PREDICATOR-NEXT: }
217+ // CHECK-PREDICATOR-NEXT: {
218+ // CHECK-PREDICATOR-NEXT: Register FirstDest = FirstMI->getOperand(0).getReg();
219+ // CHECK-PREDICATOR-NEXT: if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
220+ // CHECK-PREDICATOR-NEXT: return false;
221+ // CHECK-PREDICATOR-NEXT: }
222+ // CHECK-PREDICATOR-NEXT: if (!(FirstMI->getOperand(0).isReg() &&
223+ // CHECK-PREDICATOR-NEXT: SecondMI.getOperand(1).isReg() &&
224+ // CHECK-PREDICATOR-NEXT: FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) {
225+ // CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable())
226+ // CHECK-PREDICATOR-NEXT: return false;
227+ // CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
228+ // CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
229+ // CHECK-PREDICATOR-NEXT: if (FirstMI->getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
230+ // CHECK-PREDICATOR-NEXT: return false;
231+ // CHECK-PREDICATOR-NEXT: }
232+ // CHECK-PREDICATOR-NEXT: return true;
233+ // CHECK-PREDICATOR-NEXT: }
175234// CHECK-PREDICATOR-NEXT: } // end namespace llvm
176235// CHECK-PREDICATOR-EMPTY:
177236// CHECK-PREDICATOR-NEXT: #endif
@@ -180,6 +239,7 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta
180239// CHECK-SUBTARGET: { "test-both-fusion-predicate", "Test BothFusionPredicate", Test::TestBothFusionPredicate
181240// CHECK-SUBTARGET: { "test-commutable-fusion", "Test Commutable Fusion", Test::TestCommutableFusion
182241// CHECK-SUBTARGET: { "test-fusion", "Test Fusion", Test::TestFusion
242+ // CHECK-SUBTARGET: { "test-single-fusion", "Test SingleFusion", Test::TestSingleFusion
183243
184244// Check that we have generated `getMacroFusions()` function.
185245// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> getMacroFusions() const override;
@@ -189,5 +249,6 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta
189249// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestBothFusionPredicate)) Fusions.push_back(llvm::isTestBothFusionPredicate);
190250// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestCommutableFusion)) Fusions.push_back(llvm::isTestCommutableFusion);
191251// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) Fusions.push_back(llvm::isTestFusion);
252+ // CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestSingleFusion)) Fusions.push_back(llvm::isTestSingleFusion);
192253// CHECK-SUBTARGET-NEXT: return Fusions;
193254// CHECK-SUBTARGET-NEXT: }
0 commit comments