diff --git a/llvm/test/TableGen/GlobalISelEmitter-unannotated-dst-pattern-ops.td b/llvm/test/TableGen/GlobalISelEmitter-unannotated-dst-pattern-ops.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/GlobalISelEmitter-unannotated-dst-pattern-ops.td @@ -0,0 +1,30 @@ +// RUN: llvm-tblgen %s -gen-global-isel -optimize-match-table=true -I %p/../../include -I %p/Common -o - | FileCheck %s + +include "llvm/Target/Target.td" +include "GlobalISelEmitterCommon.td" + +def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), + [(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>; + +// CHECK: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD, +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 1*/ 38, // Rule ID 0 // +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) +// CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD, +// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, +// CHECK-NEXT: // GIR_Coverage, 0, +// CHECK-NEXT: GIR_Done, +// CHECK-NEXT: // Label 1: @38 +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 2*/ 47, // Rule ID 1 // +// CHECK-NEXT: // (add:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } ?:{ *:[i32] }:$src1, ?:{ *:[i32] }:$src2) +// CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD, +// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, +// CHECK-NEXT: // GIR_Coverage, 1, +// CHECK-NEXT: GIR_Done, +def : Pat<(add i32:$src1, i32:$src2), + (ADD $src1, $src2)>; diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -3457,7 +3457,8 @@ Expected importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, - TreePatternNode *DstChild); + TreePatternNode *DstChild, + Record *InstrOpNodeRec); Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const; @@ -4157,7 +4158,7 @@ Expected GlobalISelEmitter::importExplicitUseRenderer( action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, - TreePatternNode *DstChild) { + TreePatternNode *DstChild, Record *InstrOpNodeRec) { const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName()); if (SubOperand.hasValue()) { @@ -4245,9 +4246,15 @@ } // Otherwise, we're looking for a bog-standard RegisterClass operand. - if (auto *ChildDefInit = dyn_cast(DstChild->getLeafValue())) { - auto *ChildRec = ChildDefInit->getDef(); - + Record *ChildRec = nullptr; + if (auto *ChildDefInit = dyn_cast(DstChild->getLeafValue())) + ChildRec = ChildDefInit->getDef(); + else if (dyn_cast(DstChild->getLeafValue())) + // If operand has uninitialized leaf value (meaning the operand has not been + // prefixed with anything), try using the register class from the 'ins' + // field. + ChildRec = InstrOpNodeRec; + if (ChildRec) { ArrayRef ChildTypes = DstChild->getExtTypes(); if (ChildTypes.size() != 1) return failedImport("Dst pattern child has multiple results"); @@ -4592,7 +4599,8 @@ CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef()); auto InsertPtOrError = - importExplicitUseRenderer(InsertPt, M, DstMIBuilder, ValChild); + importExplicitUseRenderer(InsertPt, M, DstMIBuilder, ValChild, + nullptr); if (auto Error = InsertPtOrError.takeError()) return std::move(Error); InsertPt = InsertPtOrError.get(); @@ -4661,7 +4669,8 @@ } auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder, - Dst->getChild(Child)); + Dst->getChild(Child), + OperandNode); if (auto Error = InsertPtOrError.takeError()) return std::move(Error); InsertPt = InsertPtOrError.get();