From 0052238a6ed1b2978882989e6686f789a35615bb Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Fri, 14 Mar 2025 13:36:34 +0100 Subject: [PATCH 1/3] [pattern-gen] Raise error if an operands is not used in pattern --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 8c654663c19a..99258e937082 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -65,6 +65,7 @@ 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"); #ifdef LLVM_GISEL_COV_PREFIX static cl::opt @@ -142,7 +143,8 @@ enum PatternErrorT { FORMAT_LOAD, FORMAT_IMM, FORMAT, - MULTIPLE_STORES + MULTIPLE_STORES, + UNUSED_OPERANDS }; struct PatternError { PatternErrorT Type; @@ -163,7 +165,8 @@ llvm::Statistic *ErrorStats[] = {nullptr, &PatternGenNumErrorFormatLoad, &PatternGenNumErrorFormatImm, &PatternGenNumErrorFormat, - &PatternGenNumErrorMultipleStores}; + &PatternGenNumErrorMultipleStores, + &PatternGenNumErrorUnusedOperand}; static const std::unordered_map CmpStr = { {CmpInst::Predicate::ICMP_EQ, "SETEQ"}, @@ -1366,6 +1369,12 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { std::string OutsString; std::string InsString; for (size_t I = 0; I < CurInstr->fields.size() - 1; I++) { + 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; + } if (PatternArgs[I].In) { InsString += PatternArgs[I].ArgTypeStr + ":$" + std::string(CurInstr->fields[I].ident) + ", "; From 51c7f262e3b7c2ee9342aac23e4367a03e54e774 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Fri, 14 Mar 2025 14:20:11 +0100 Subject: [PATCH 2/3] [pattern-gen] Detect operand missmatches (In/Out) --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 99258e937082..8b4981e33ed9 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -66,6 +66,7 @@ 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 @@ -1369,12 +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) + ", "; From 1e4edbe62615df9f2effc0451fb6e9807060ccae Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Fri, 14 Mar 2025 14:21:29 +0100 Subject: [PATCH 3/3] [pattern-gen] Parser: IMM operands are always inputs --- llvm/tools/pattern-gen/lib/Parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; }