diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 8c654663c19a..8b4981e33ed9 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -65,6 +65,8 @@ STATISTIC(PatternGenNumErrorFormatLoad, "Errors of type: FORMAT_LOAD"); STATISTIC(PatternGenNumErrorFormatImm, "Errors of type: FORMAT_IMM"); STATISTIC(PatternGenNumErrorFormat, "Errors of type: FORMAT"); STATISTIC(PatternGenNumErrorMultipleStores, "Errors of type: MULTIPLE STORES"); +STATISTIC(PatternGenNumErrorUnusedOperand, "Errors of type: UNUSED_OPERAND"); +STATISTIC(PatternGenNumErrorOperandMissmatch, "Errors of type: OPERAND_MISSMATCH"); #ifdef LLVM_GISEL_COV_PREFIX static cl::opt @@ -142,7 +144,8 @@ enum PatternErrorT { FORMAT_LOAD, FORMAT_IMM, FORMAT, - MULTIPLE_STORES + MULTIPLE_STORES, + UNUSED_OPERANDS }; struct PatternError { PatternErrorT Type; @@ -163,7 +166,8 @@ llvm::Statistic *ErrorStats[] = {nullptr, &PatternGenNumErrorFormatLoad, &PatternGenNumErrorFormatImm, &PatternGenNumErrorFormat, - &PatternGenNumErrorMultipleStores}; + &PatternGenNumErrorMultipleStores, + &PatternGenNumErrorUnusedOperand}; static const std::unordered_map CmpStr = { {CmpInst::Predicate::ICMP_EQ, "SETEQ"}, @@ -1366,6 +1370,30 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { std::string OutsString; std::string InsString; for (size_t I = 0; I < CurInstr->fields.size() - 1; I++) { + // TODO: move to helper func + + // handle unused operands + if (!PatternArgs[I].In && !PatternArgs[I].Out) { + llvm::errs() << "Pattern Generation failed for " << MF.getName() << ": " + << "Operand '" << CurInstr->fields[I].ident << "' not used in pattern!\n"; + ++PatternGenNumErrorUnusedOperand; + return true; + } + + // check for missmatches between operands + if ((CurInstr->fields[I].type & CDSLInstr::IN) && !PatternArgs[I].In) { + llvm::errs() << "Pattern Generation failed for " << MF.getName() << ": " + << "Operand '" << CurInstr->fields[I].ident << "' should be an input!\n"; + ++PatternGenNumErrorOperandMissmatch; + return true; + } + if ((CurInstr->fields[I].type & CDSLInstr::OUT) && !PatternArgs[I].Out) { + llvm::errs() << "Pattern Generation failed for " << MF.getName() << ": " + << "Operand '" << CurInstr->fields[I].ident << "' should be an output!\n"; + ++PatternGenNumErrorOperandMissmatch; + return true; + } + if (PatternArgs[I].In) { InsString += PatternArgs[I].ArgTypeStr + ":$" + std::string(CurInstr->fields[I].ident) + ", "; diff --git a/llvm/tools/pattern-gen/lib/Parser.cpp b/llvm/tools/pattern-gen/lib/Parser.cpp index 703f245b1ce9..f65efb2d480a 100644 --- a/llvm/tools/pattern-gen/lib/Parser.cpp +++ b/llvm/tools/pattern-gen/lib/Parser.cpp @@ -1371,7 +1371,7 @@ void ParseArguments(TokenStream &ts, CDSLInstr &instr) { strNew = std::regex_replace(str, std::regex("\\{" + fstr + "\\}"), "$" + fstr); if (strNew != str) - f.type = (CDSLInstr::FieldType)(f.type | CDSLInstr::FieldType::IMM); + f.type = (CDSLInstr::FieldType)(f.type | CDSLInstr::FieldType::IMM | CDSLInstr::FieldType::IN); str = strNew; }