mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-17 08:21:13 +00:00
[TableGen] Fix wrong codegen of BothFusionPredicateWithMCInstPredicate (#83990)
We should generate the `MCInstPredicate` twice, one with `FirstMI` and another with `SecondMI`. (cherry picked from commit de1f33873beff93063577195e1214a9509e229e0)
This commit is contained in:
parent
a91b9bd9c7
commit
69d9b15fe8
@ -620,7 +620,7 @@ class SecondFusionPredicateWithMCInstPredicate<MCInstPredicate pred>
|
||||
: FusionPredicateWithMCInstPredicate<second_fusion_target, pred>;
|
||||
// The pred will be applied on both firstMI and secondMI.
|
||||
class BothFusionPredicateWithMCInstPredicate<MCInstPredicate pred>
|
||||
: FusionPredicateWithMCInstPredicate<second_fusion_target, pred>;
|
||||
: FusionPredicateWithMCInstPredicate<both_fusion_target, pred>;
|
||||
|
||||
// Tie firstOpIdx and secondOpIdx. The operand of `FirstMI` at position
|
||||
// `firstOpIdx` should be the same as the operand of `SecondMI` at position
|
||||
|
@ -34,6 +34,11 @@ let Namespace = "Test" in {
|
||||
def Inst0 : TestInst<0>;
|
||||
def Inst1 : TestInst<1>;
|
||||
|
||||
def BothFusionPredicate: BothFusionPredicateWithMCInstPredicate<CheckRegOperand<0, X0>>;
|
||||
def TestBothFusionPredicate: Fusion<"test-both-fusion-predicate", "HasBothFusionPredicate",
|
||||
"Test BothFusionPredicate",
|
||||
[BothFusionPredicate]>;
|
||||
|
||||
def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion",
|
||||
CheckOpcode<[Inst0]>,
|
||||
CheckAll<[
|
||||
@ -45,6 +50,7 @@ def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion",
|
||||
// CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_DECL
|
||||
// CHECK-PREDICATOR-EMPTY:
|
||||
// CHECK-PREDICATOR-NEXT: namespace llvm {
|
||||
// CHECK-PREDICATOR-NEXT: bool isTestBothFusionPredicate(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
|
||||
// CHECK-PREDICATOR-NEXT: bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
|
||||
// CHECK-PREDICATOR-NEXT: } // end namespace llvm
|
||||
// CHECK-PREDICATOR-EMPTY:
|
||||
@ -54,6 +60,24 @@ def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion",
|
||||
// CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_IMPL
|
||||
// CHECK-PREDICATOR-EMPTY:
|
||||
// CHECK-PREDICATOR-NEXT: namespace llvm {
|
||||
// CHECK-PREDICATOR-NEXT: bool isTestBothFusionPredicate(
|
||||
// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII,
|
||||
// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI,
|
||||
// CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI,
|
||||
// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) {
|
||||
// CHECK-PREDICATOR-NEXT: auto &MRI = SecondMI.getMF()->getRegInfo();
|
||||
// CHECK-PREDICATOR-NEXT: {
|
||||
// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = FirstMI;
|
||||
// CHECK-PREDICATOR-NEXT: if (MI->getOperand(0).getReg() != Test::X0)
|
||||
// CHECK-PREDICATOR-NEXT: return false;
|
||||
// CHECK-PREDICATOR-NEXT: }
|
||||
// CHECK-PREDICATOR-NEXT: {
|
||||
// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI;
|
||||
// CHECK-PREDICATOR-NEXT: if (MI->getOperand(0).getReg() != Test::X0)
|
||||
// CHECK-PREDICATOR-NEXT: return false;
|
||||
// CHECK-PREDICATOR-NEXT: }
|
||||
// CHECK-PREDICATOR-NEXT: return true;
|
||||
// CHECK-PREDICATOR-NEXT: }
|
||||
// CHECK-PREDICATOR-NEXT: bool isTestFusion(
|
||||
// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII,
|
||||
// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI,
|
||||
@ -106,6 +130,7 @@ def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion",
|
||||
|
||||
// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> TestGenSubtargetInfo::getMacroFusions() const {
|
||||
// CHECK-SUBTARGET-NEXT: std::vector<MacroFusionPredTy> Fusions;
|
||||
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestBothFusionPredicate)) Fusions.push_back(llvm::isTestBothFusionPredicate);
|
||||
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) Fusions.push_back(llvm::isTestFusion);
|
||||
// CHECK-SUBTARGET-NEXT: return Fusions;
|
||||
// CHECK-SUBTARGET-NEXT: }
|
||||
|
@ -152,8 +152,7 @@ void MacroFusionPredicatorEmitter::emitFirstPredicate(Record *Predicate,
|
||||
<< "if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))\n";
|
||||
OS.indent(4) << " return false;\n";
|
||||
OS.indent(2) << "}\n";
|
||||
} else if (Predicate->isSubClassOf(
|
||||
"FirstFusionPredicateWithMCInstPredicate")) {
|
||||
} else if (Predicate->isSubClassOf("FusionPredicateWithMCInstPredicate")) {
|
||||
OS.indent(2) << "{\n";
|
||||
OS.indent(4) << "const MachineInstr *MI = FirstMI;\n";
|
||||
OS.indent(4) << "if (";
|
||||
@ -173,7 +172,7 @@ void MacroFusionPredicatorEmitter::emitFirstPredicate(Record *Predicate,
|
||||
void MacroFusionPredicatorEmitter::emitSecondPredicate(Record *Predicate,
|
||||
PredicateExpander &PE,
|
||||
raw_ostream &OS) {
|
||||
if (Predicate->isSubClassOf("SecondFusionPredicateWithMCInstPredicate")) {
|
||||
if (Predicate->isSubClassOf("FusionPredicateWithMCInstPredicate")) {
|
||||
OS.indent(2) << "{\n";
|
||||
OS.indent(4) << "const MachineInstr *MI = &SecondMI;\n";
|
||||
OS.indent(4) << "if (";
|
||||
@ -185,7 +184,7 @@ void MacroFusionPredicatorEmitter::emitSecondPredicate(Record *Predicate,
|
||||
OS.indent(2) << "}\n";
|
||||
} else {
|
||||
PrintFatalError(Predicate->getLoc(),
|
||||
"Unsupported predicate for first instruction: " +
|
||||
"Unsupported predicate for second instruction: " +
|
||||
Predicate->getType()->getAsString());
|
||||
}
|
||||
}
|
||||
@ -196,9 +195,8 @@ void MacroFusionPredicatorEmitter::emitBothPredicate(Record *Predicate,
|
||||
if (Predicate->isSubClassOf("FusionPredicateWithCode"))
|
||||
OS << Predicate->getValueAsString("Predicate");
|
||||
else if (Predicate->isSubClassOf("BothFusionPredicateWithMCInstPredicate")) {
|
||||
Record *MCPred = Predicate->getValueAsDef("Predicate");
|
||||
emitFirstPredicate(MCPred, PE, OS);
|
||||
emitSecondPredicate(MCPred, PE, OS);
|
||||
emitFirstPredicate(Predicate, PE, OS);
|
||||
emitSecondPredicate(Predicate, PE, OS);
|
||||
} else if (Predicate->isSubClassOf("TieReg")) {
|
||||
int FirstOpIdx = Predicate->getValueAsInt("FirstOpIdx");
|
||||
int SecondOpIdx = Predicate->getValueAsInt("SecondOpIdx");
|
||||
|
Loading…
x
Reference in New Issue
Block a user