From 2a534473663668015fab21505f72d73fa8f7f1f6 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Tue, 8 Apr 2025 10:55:09 +0200 Subject: [PATCH 01/16] pattern-gen: ignore TargetOpcode::G_CONSTANT_FOLD_BARRIER --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 8b4981e33ed9..34440d636ae6 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -579,7 +579,7 @@ struct UnopNode : public PatternNode { std::string TypeStr = lltToString(Type); // ignore bitcast ops for now - if (Op == TargetOpcode::G_BITCAST) + if ((Op == TargetOpcode::G_BITCAST) || (Op == TargetOpcode::G_CONSTANT_FOLD_BARRIER)) return Operand->patternString(); return "(" + TypeStr + " (" + std::string(UnopStr.at(Op)) + " " + @@ -587,7 +587,7 @@ struct UnopNode : public PatternNode { } LLT getRegisterTy(int OperandId) const override { - if (OperandId == -1 && Op != TargetOpcode::G_BITCAST) + if (OperandId == -1 && Op != TargetOpcode::G_BITCAST && Op != TargetOpcode::G_CONSTANT_FOLD_BARRIER) return Type; return Operand->getRegisterTy(OperandId); } @@ -1040,6 +1040,7 @@ static PatternOrError traverse(MachineRegisterInfo &MRI, MachineInstr &Cur) { return std::make_pair(SUCCESS, std::move(Node)); } + case TargetOpcode::G_CONSTANT_FOLD_BARRIER: case TargetOpcode::G_ANYEXT: case TargetOpcode::G_SEXT: case TargetOpcode::G_ZEXT: From 9f02feec43f6d3ef6cc7f9d99b025f3ed4e6dff0 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Tue, 8 Apr 2025 12:28:29 +0200 Subject: [PATCH 02/16] pattern-gen: do not print invalid patterns --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 34440d636ae6..97402b87b6af 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -1363,10 +1363,6 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { return true; } - llvm::outs() << "Pattern for " << InstName << ": " << Node->patternString() - << '\n'; - ++PatternGenNumPatternsGenerated; - LLT OutType = LLT(); std::string OutsString; std::string InsString; @@ -1410,6 +1406,11 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { } } + llvm::outs() << "Pattern for " << InstName << ": " << Node->patternString() + << '\n'; + ++PatternGenNumPatternsGenerated; + + InsString = InsString.substr(0, InsString.size() - 2); OutsString = OutsString.substr(0, OutsString.size() - 2); From 331da4d9880eb5f62fa586b663dcb5de63e43377 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Mon, 20 Oct 2025 10:34:50 +0200 Subject: [PATCH 03/16] [pattern-gen] Parser: fix poison mask in gen_subscript --- llvm/tools/pattern-gen/lib/Parser.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/tools/pattern-gen/lib/Parser.cpp b/llvm/tools/pattern-gen/lib/Parser.cpp index b7e4a9eac0bc..f1237ab98c8b 100644 --- a/llvm/tools/pattern-gen/lib/Parser.cpp +++ b/llvm/tools/pattern-gen/lib/Parser.cpp @@ -268,10 +268,12 @@ Value gen_subscript(TokenStream &ts, llvm::Function *func, llvm::Value *mask = (len == llLen) ? llvm::ConstantInt::get(upper.ll->getType(), 0) - : build.CreateShl(llvm::ConstantInt::get(upper.ll->getType(), 1), + : build.CreateShl( + llvm::ConstantInt::get(llvm::Type::getIntNTy(ctx, len + 1), 1), len); - mask = - build.CreateSub(mask, llvm::ConstantInt::get(upper.ll->getType(), 1)); + mask = build.CreateSub(mask, llvm::ConstantInt::get(mask->getType(), 1)); + mask = (len < left.ll->getType()->getIntegerBitWidth()) ? build.CreateZExt(mask, left.ll->getType()) : ((build.CreateTrunc(mask, left.ll->getType())) ? : mask); + left.ll = build.CreateAnd(left.ll, mask); left.bitWidth = len; From ecb85565cc1678288bd73c4b514f63b685498e48 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Thu, 22 Jan 2026 22:25:56 +0100 Subject: [PATCH 04/16] PatternGen: support X[0] in parser --- llvm/tools/pattern-gen/lib/Parser.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/llvm/tools/pattern-gen/lib/Parser.cpp b/llvm/tools/pattern-gen/lib/Parser.cpp index f1237ab98c8b..63e29b550cef 100644 --- a/llvm/tools/pattern-gen/lib/Parser.cpp +++ b/llvm/tools/pattern-gen/lib/Parser.cpp @@ -807,6 +807,17 @@ Value ParseExpressionTerminal(TokenStream &ts, llvm::Function *func, if (t.ident.str == "X" || t.ident.str == "XW") { bool sizeIs32 = t.ident.str == "XW"; pop_cur(ts, ABrOpen); + if (ts.Peek().type == IntLiteral) { // Handle X[0] + auto idx = pop_cur(ts, IntLiteral); + pop_cur(ts, ABrClose); + if (idx.literal.value == 0) // X[0] -> 0 + return Value( + llvm::ConstantInt::get(llvm::Type::getIntNTy(ctx, sizeIs32 ? 32 : xlen), + 0, true), + true); + else // X[1],... + not_implemented(ts); + } auto ident = pop_cur(ts, Identifier).ident; pop_cur(ts, ABrClose); From d6828248b4daee02c8461a38bd1b36ba8e57f912 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Wed, 22 Oct 2025 11:45:38 +0200 Subject: [PATCH 05/16] [pattern-gen] Handle G_SELECT in traverseRegLoad --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 97402b87b6af..06b88b6f16f9 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -937,8 +937,28 @@ static PatternOrError traverseRegLoad(MachineRegisterInfo &MRI, ReadOffset = Offset->getOperand(1).getCImm()->getLimitedValue(); } if (AddrI->getOpcode() == TargetOpcode::G_SELECT) { - // TODO: implement this! - return pError(FORMAT_LOAD, AddrI); + assert(AddrI->getOperand(1).isReg() && "expected register"); + auto CondInstr = AddrI->getOperand(1); + auto CondReg = CondInstr.getReg(); + auto [ErrCond, CondNode] = traverse(MRI, *MRI.getVRegDef(CondReg)); + if (ErrCond) + return PError(ErrCond); + assert(AddrI->getOperand(2).isReg() && "expected register"); + auto TrueInstr = AddrI->getOperand(2); + auto TrueReg = TrueInstr.getReg(); + auto [ErrTrue, TrueNode] = traverseRegLoad(MRI, Cur, ReadSize, MRI.getVRegDef(TrueReg)); + if (ErrTrue) + return PError(ErrTrue); + assert(AddrI->getOperand(3).isReg() && "expected register"); + auto FalseInstr = AddrI->getOperand(3); + auto FalseReg = FalseInstr.getReg(); + auto [ErrFalse, FalseNode] = traverseRegLoad(MRI, Cur, ReadSize, MRI.getVRegDef(FalseReg)); + if (ErrFalse) + return PError(ErrFalse); + auto Node = std::make_unique( + MRI.getType(Cur.getOperand(0).getReg()), AddrI->getOpcode(), + std::move(CondNode), std::move(TrueNode), std::move(FalseNode)); + return PPattern(std::move(Node)); } if (AddrI->getOpcode() != TargetOpcode::COPY) return pError(FORMAT_LOAD, AddrI); From acfb3068f2cf35b29afbb6350a46125c6ac50588 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Wed, 29 Oct 2025 21:32:15 +0100 Subject: [PATCH 06/16] PatternGen: expose --print-mir --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 4 ++++ llvm/tools/pattern-gen/Main.cpp | 5 ++++- llvm/tools/pattern-gen/PatternGen.hpp | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 06b88b6f16f9..72d661b12b3e 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -1352,6 +1352,10 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { MayLoad = 0; MayStore = 0; + if (PatternGenArgs::Args.DumpMIR) { + MF.dump(); + } + std::string InstName = MF.getName().str().substr(4); std::string InstNameO = InstName; ++PatternGenNumInstructionsProcessed; diff --git a/llvm/tools/pattern-gen/Main.cpp b/llvm/tools/pattern-gen/Main.cpp index 62eea631137a..25443ea631e5 100644 --- a/llvm/tools/pattern-gen/Main.cpp +++ b/llvm/tools/pattern-gen/Main.cpp @@ -55,6 +55,8 @@ static cl::opt SkipVerify("skip-verify", cl::cat(ToolOptions)); static cl::opt PrintIR("print-ir", cl::desc("Print LLVM-IR module."), cl::cat(ToolOptions)); +static cl::opt PrintMIR("print-mir", cl::desc("Print LLVM-MIR functions."), + cl::cat(ToolOptions)); static cl::opt NoExtend( "no-extend", cl::desc("Do not apply CDSL typing rules (Use C-like type inference)."), @@ -165,7 +167,8 @@ int main(int argc, char **argv) { PGArgsStruct Args{.Mattr = "", .OptLevel = Opt, .Predicates = Predicates, - .Is64Bit = (XLen == 64)}; + .Is64Bit = (XLen == 64), + .DumpMIR = PrintMIR.getValue()}; optimizeBehavior(Mod.get(), Instrs, irOut, Args); if (PrintIR) diff --git a/llvm/tools/pattern-gen/PatternGen.hpp b/llvm/tools/pattern-gen/PatternGen.hpp index 18e8d8e2f526..cb8b288600e7 100644 --- a/llvm/tools/pattern-gen/PatternGen.hpp +++ b/llvm/tools/pattern-gen/PatternGen.hpp @@ -10,6 +10,7 @@ struct PGArgsStruct llvm::CodeGenOptLevel OptLevel; std::string Predicates; bool Is64Bit; + bool DumpMIR; }; int optimizeBehavior(llvm::Module* M, std::vector const& Instrs, std::ostream& OstreamIR, PGArgsStruct Args); From 915d0a7aab53b0164d160a07100f426d4278374e Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Wed, 22 Oct 2025 11:46:05 +0200 Subject: [PATCH 07/16] [pattern-gen] Write optimized llvm-ir to irOut --- llvm/tools/pattern-gen/Main.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/llvm/tools/pattern-gen/Main.cpp b/llvm/tools/pattern-gen/Main.cpp index 25443ea631e5..14dca1923a32 100644 --- a/llvm/tools/pattern-gen/Main.cpp +++ b/llvm/tools/pattern-gen/Main.cpp @@ -130,15 +130,6 @@ int main(int argc, char **argv) { auto Mod = std::make_unique("mod", Ctx); auto Instrs = ParseCoreDSL2(Ts, (XLen == 64), Mod.get(), NoExtend); - if (irOut) { - std::string Str; - raw_string_ostream OS(Str); - OS << *Mod; - OS.flush(); - irOut << Str << "\n"; - irOut.close(); - } - if (!SkipVerify) if (verifyModule(*Mod, &errs())) return -1; @@ -171,6 +162,10 @@ int main(int argc, char **argv) { .DumpMIR = PrintMIR.getValue()}; optimizeBehavior(Mod.get(), Instrs, irOut, Args); + + if (irOut) + irOut.close(); + if (PrintIR) llvm::outs() << *Mod << "\n"; if (!SkipFmt) From 2dbd2d3addf4b83c63fc04502d3fdc9988b89ae1 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Tue, 17 Feb 2026 09:10:12 +0100 Subject: [PATCH 08/16] llvm/lib/CodeGen/GlobalISel/PatternGen.cpp: add missing LLVM_DEBUG --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 72d661b12b3e..2b46f9ecc44d 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -1353,7 +1353,7 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { MayStore = 0; if (PatternGenArgs::Args.DumpMIR) { - MF.dump(); + LLVM_DEBUG(MF.dump()); } std::string InstName = MF.getName().str().substr(4); From f7e2a3fd0067fa630d4f268738de2d2571f75532 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Mon, 2 Feb 2026 14:18:07 +0100 Subject: [PATCH 09/16] llvm/tools/pattern-gen: parse attribute values (and support llvm_type) --- llvm/tools/pattern-gen/lib/InstrInfo.hpp | 2 + llvm/tools/pattern-gen/lib/Parser.cpp | 208 ++++++++++++++++++----- 2 files changed, 166 insertions(+), 44 deletions(-) diff --git a/llvm/tools/pattern-gen/lib/InstrInfo.hpp b/llvm/tools/pattern-gen/lib/InstrInfo.hpp index 0b080f7d543a..e3ace61782c7 100644 --- a/llvm/tools/pattern-gen/lib/InstrInfo.hpp +++ b/llvm/tools/pattern-gen/lib/InstrInfo.hpp @@ -38,10 +38,12 @@ struct CDSLInstr std::string_view ident; uint32_t identIdx; FieldType type; + std::string llvm_type; }; uint8_t size; std::string name; + std::string llvm_instr; std::string mnemonic; std::string argString; diff --git a/llvm/tools/pattern-gen/lib/Parser.cpp b/llvm/tools/pattern-gen/lib/Parser.cpp index 63e29b550cef..a9972d62fa04 100644 --- a/llvm/tools/pattern-gen/lib/Parser.cpp +++ b/llvm/tools/pattern-gen/lib/Parser.cpp @@ -107,6 +107,19 @@ static void warning(const char *msg, TokenStream &ts) { fprintf(stderr, "%s:%i: warning: %s\n", ts.path.c_str(), ts.lineNumber, msg); } +#include "llvm/ADT/Twine.h" + +static void __attribute__((noreturn)) +error(const llvm::Twine &msg, TokenStream &ts) { + std::string s = msg.str(); // materialize once + error(s.c_str(), ts); +} + +static void warning(const llvm::Twine &msg, TokenStream &ts) { + std::string s = msg.str(); + warning(s.c_str(), ts); +} + static void __attribute__((noreturn)) syntax_error(TokenStream &ts) { error("syntax error", ts); } @@ -1180,64 +1193,168 @@ void ParseScope(TokenStream &ts, llvm::Function *func, pop_cur(ts, CBrClose); } -int ParseAttributes(TokenStream &ts) { - using FieldType = CDSLInstr::FieldType; + +struct AttrValue { + enum Kind { + Bool, // [[is_reg]] + Int, // [[opcode=7'ha]] + String // [[llvm_type="seal5_simm3"]] + } kind; + + uint64_t intVal; + std::string strVal; + + static AttrValue makeBool() { return {Bool, 0, {}}; } + static AttrValue makeInt(uint64_t v) { return {Int, v, {}}; } + static AttrValue makeString(std::string s) { + AttrValue v; + v.kind = String; + v.strVal = std::move(s); + return v; + } + static AttrValue makeString(std::string_view s) { + AttrValue a; + a.kind = String; + a.strVal.assign(s.data(), s.size()); // explicit copy + return a; + } +}; + + +using AttrMap = llvm::StringMap; +AttrMap ParseAttributes(TokenStream &ts) { + // using FieldType = CDSLInstr::FieldType; // Sign bit specifies whether to OR or AND the mask, so just do // ~MY_FIELD to unset myField. - const static llvm::DenseMap> - attrMap = {{"is_unsigned", {~FieldType::SIGNED_REG, 0}}, - {"is_signed", {FieldType::SIGNED_REG, 0}}, - {"is_imm", {FieldType::IMM, 0}}, - {"is_reg", {FieldType::REG, 0}}, - {"in", {FieldType::IN, 0}}, - {"out", {FieldType::OUT, 0}}, - {"inout", {(FieldType::IN | FieldType::OUT), 0}}, - {"is_32_bit", {FieldType::IS_32_BIT, 0}}}; - - uint acc = 0; + // const static llvm::DenseMap> + // attrMap = {{"is_unsigned", {~FieldType::SIGNED_REG, 0}}, + // {"is_signed", {FieldType::SIGNED_REG, 0}}, + // {"is_imm", {FieldType::IMM, 0}}, + // {"is_reg", {FieldType::REG, 0}}, + // {"in", {FieldType::IN, 0}}, + // {"out", {FieldType::OUT, 0}}, + // {"inout", {(FieldType::IN | FieldType::OUT), 0}}, + // {"is_32_bit", {FieldType::IS_32_BIT, 0}}}; + + // uint acc = 0; + AttrMap attrs; while (ts.Peek().type == ABrOpen) { for (int i = 0; i < 2; i++) pop_cur(ts, ABrOpen); - bool allowArg = true; + // bool allowArg = true; auto ident = pop_cur(ts, Identifier).ident; - std::string attrName = std::string{ident.str}; - std::transform(attrName.begin(), attrName.end(), attrName.begin(), + std::string name = std::string{ident.str}; + std::transform(name.begin(), name.end(), name.begin(), [](unsigned char c) { return std::tolower(c); }); - auto iter = attrMap.find(attrName); - if (iter != attrMap.end()) { - uint op = iter->getSecond().first; - allowArg = iter->getSecond().second; - if (op & (1UL << (std::numeric_limits::digits - 1))) - acc &= op; - else - acc |= op; - } - + AttrValue value = AttrValue::makeBool(); if (pop_cur_if(ts, Assignment)) { - if (!allowArg) - error("attribute does not take an argument", ts); - if (!llvm::find(std::array{Identifier, IntLiteral, StringLiteral}, - ts.Pop().type)) - error("invalid attribute", ts); + auto tok = ts.Pop(); + switch (tok.type) { + case IntLiteral: + value = AttrValue::makeInt(tok.literal.value); + break; + case StringLiteral: + value = AttrValue::makeString(tok.strLit.str); + break; + case Identifier: + value = AttrValue::makeString(tok.ident.str); + break; + default: + error("invalid attribute value", ts); + } } + attrs[name] = std::move(value); + + // auto iter = attrMap.find(attrName); + // if (iter != attrMap.end()) { + // uint op = iter->getSecond().first; + // allowArg = iter->getSecond().second; + // if (op & (1UL << (std::numeric_limits::digits - 1))) + // acc &= op; + // else + // acc |= op; + // } + + // if (pop_cur_if(ts, Assignment)) { + // if (!allowArg) + // error("attribute does not take an argument", ts); + // if (!llvm::find(std::array{Identifier, IntLiteral, StringLiteral}, + // ts.Pop().type)) + // error("invalid attribute", ts); + // } for (int i = 0; i < 2; i++) pop_cur(ts, ABrClose); } + return attrs; + + // return (CDSLInstr::FieldType)acc; +} + +void ApplyOperandAttributes(const AttrMap &attrs, CDSLInstr::Field &op, TokenStream &ts) { + using FT = CDSLInstr::FieldType; + + int type = op.type; + for (auto &kv : attrs) { + auto name = kv.first(); + auto &val = kv.second; + + if (name == "is_reg") { + type |= FT::REG; + } else if (name == "is_imm") { + type |= FT::IMM; + } else if (name == "in") { + type |= FT::IN; + } else if (name == "out") { + type |= FT::OUT; + } else if (name == "inout") { + type |= (FT::IN | FT::OUT); + } else if (name == "is_signed") { + type |= FT::SIGNED_REG; + } else if (name == "is_unsigned") { + type &= (~FT::SIGNED_REG); + } else if (name == "is_32_bit") { + type |= FT::IS_32_BIT; + } else if (name == "llvm_type") { + if (val.kind != AttrValue::String) + error("llvm_type must be a string", ts); + op.llvm_type = val.strVal; + // } else if (name == "reg_class") { + // op.regClass = val.strVal; + } else { + warning("unknown operand attribute: " + name, ts); + } + + } + op.type = (CDSLInstr::FieldType)type; +} - return (CDSLInstr::FieldType)acc; +void ParseOperandAttributes(TokenStream &ts, CDSLInstr::Field &op) { + AttrMap attrs = ParseAttributes(ts); + ApplyOperandAttributes(attrs, op, ts); } -int ParseOperandAttributes(TokenStream &ts) { - return ParseAttributes(ts); +void ApplyInstructionAttributes(const AttrMap &attrs, CDSLInstr &instr, TokenStream &ts) { + for (auto &kv : attrs) { + auto name = kv.first(); + auto &val = kv.second; + + if (name == "llvm_instr") { + if (val.kind != AttrValue::String) + error("llvm_instr must be a string", ts); + instr.llvm_instr = val.strVal; + } else { + warning("unknown instruction attribute: " + name, ts); + } + } } void ParseInstructionAttributes(TokenStream &ts, CDSLInstr &instr) { - // ignore attributes - ParseAttributes(ts); + AttrMap attrs = ParseAttributes(ts); + ApplyInstructionAttributes(attrs, instr, ts); } void ParseSetAttributes(TokenStream &ts) { @@ -1253,14 +1370,17 @@ void ParseOperands(TokenStream &ts, CDSLInstr &instr) { while (peek_is_type(ts)) { auto vd = ParseDefinition(ts); - uint type = ParseOperandAttributes(ts) | CDSLInstr::FieldType::NON_CONST; - type = (type & ~CDSLInstr::SIGNED) | (vd.sgn ? CDSLInstr::SIGNED : 0); - - instr.fields.push_back( - CDSLInstr::Field{.len = (uint8_t)vd.bitSize, - .ident = vd.ident, - .identIdx = vd.identIdx, - .type = (CDSLInstr::FieldType)type}); + + CDSLInstr::Field op = CDSLInstr::Field{.len = (uint8_t)vd.bitSize, + .ident = vd.ident, + .identIdx = vd.identIdx, + .type = CDSLInstr::FieldType::NON_CONST}; + + ParseOperandAttributes(ts, op); + + op.type = (CDSLInstr::FieldType)((op.type & ~CDSLInstr::SIGNED) | (vd.sgn ? CDSLInstr::SIGNED : 0)); + + instr.fields.push_back(op); pop_cur(ts, Semicolon); } From d90c2ca4af37d35923c7453ac6341468ca1905e3 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Mon, 2 Feb 2026 14:17:57 +0100 Subject: [PATCH 10/16] llvm/lib/CodeGen/GlobalISel/PatternGen.cpp: handle llvm_type --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 2b46f9ecc44d..72f4116e618c 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -210,8 +210,10 @@ std::string lltToRegTypeStr(LLT Type) { return "invalid"; } -std::string makeImmTypeStr(int Size, bool Signed) { - return (Signed ? "simm" : "uimm") + std::to_string(Size); +std::string makeImmTypeStr(int Size, bool Signed, std::string llvm_type) { + if (llvm_type.empty()) + return (Signed ? "simm" : "uimm") + std::to_string(Size); + return llvm_type; } struct PatternNode { @@ -623,13 +625,14 @@ struct RegisterNode : public PatternNode { StringRef Name; int Size; bool Sext; + std::string llvm_type; size_t RegIdx; RegisterNode(LLT Type, StringRef Name, size_t RegIdx, bool IsImm, int Size, - bool Sext) + bool Sext, std::string llvm_type) : PatternNode(PN_Register, Type, IsImm), Name(Name), Size(Size), - Sext(Sext), RegIdx(RegIdx) {} + Sext(Sext), llvm_type(llvm_type), RegIdx(RegIdx) {} std::string patternString() override { std::string TypeStr = lltToString(Type); @@ -637,8 +640,12 @@ struct RegisterNode : public PatternNode { if (IsImm) { // Immediate Operands - return ("(" + RegT + " ") + (Sext ? "simm" : "uimm") + - std::to_string(Size) + ":$" + std::string(Name) + ")"; + std::string pre; + if (llvm_type.empty()) + pre = (Sext ? "simm" : "uimm") + std::to_string(Size); + else + pre = llvm_type; + return ("(" + RegT + " ") + pre + ":$" + std::string(Name) + ")"; } // Vector Types (currently rv32 only) @@ -979,7 +986,7 @@ static PatternOrError traverseRegLoad(MachineRegisterInfo &MRI, assert(Cur.getOperand(0).isReg() && "expected register"); std::unique_ptr Node = std::make_unique( - Type, Field->ident, Idx, false, Type.getSizeInBits(), false); + Type, Field->ident, Idx, false, Type.getSizeInBits(), false, Field->llvm_type); bool SizeMismatch = (int)Type.getSizeInBits() != ReadSize; @@ -1162,7 +1169,7 @@ static PatternOrError traverse(MachineRegisterInfo &MRI, MachineInstr &Cur) { PatternArgs[Idx].In = true; PatternArgs[Idx].Llt = LLT(); PatternArgs[Idx].ArgTypeStr = - makeImmTypeStr(Field->len, Field->type & CDSLInstr::SIGNED); + makeImmTypeStr(Field->len, Field->type & CDSLInstr::SIGNED, Field->llvm_type); if (Field == nullptr) return std::make_pair(FORMAT_IMM, nullptr); @@ -1171,7 +1178,7 @@ static PatternOrError traverse(MachineRegisterInfo &MRI, MachineInstr &Cur) { return std::make_pair( SUCCESS, std::make_unique( MRI.getType(Cur.getOperand(0).getReg()), Field->ident, - Idx, true, Field->len, Field->type & CDSLInstr::SIGNED)); + Idx, true, Field->len, Field->type & CDSLInstr::SIGNED, Field->llvm_type)); } // Else COPY is just a pass-through. From 6210b25b0b2f1dde2376f6f6c7591ec20856111a Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Sun, 8 Mar 2026 20:56:59 +0100 Subject: [PATCH 11/16] llvm/tools/pattern-gen/CMakeLists.txt: add RISCVCodeGen & RISCVDesc deps --- llvm/tools/pattern-gen/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/tools/pattern-gen/CMakeLists.txt b/llvm/tools/pattern-gen/CMakeLists.txt index 4ae80d0f3227..079138fa9624 100644 --- a/llvm/tools/pattern-gen/CMakeLists.txt +++ b/llvm/tools/pattern-gen/CMakeLists.txt @@ -20,6 +20,8 @@ set(LLVM_LINK_COMPONENTS TransformUtils Vectorize Passes + RISCVCodeGen + RISCVDesc ) include_directories(../../lib/Target/RISCV) From 2f4cfe5e5a91247e3f50cb222fee85d9ca9f0495 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Thu, 30 Jul 2026 15:27:23 +0200 Subject: [PATCH 12/16] PatternGen: print mnemonic for instr --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index 72f4116e618c..f5f8323113dd 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -1374,6 +1374,7 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { "implementation function without instruction definition"); CurInstr = It.base(); } + std::string InstMnemonic = CurInstr->mnemonic; // We use the PatternArgs vector to store additional information // about parameters that may be found during pattern gen. @@ -1437,7 +1438,7 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { } } - llvm::outs() << "Pattern for " << InstName << ": " << Node->patternString() + llvm::outs() << "Pattern for " << InstName << " [" << InstMnemonic << "]: " << Node->patternString() << '\n'; ++PatternGenNumPatternsGenerated; From 81a5f3eefb4bdad8cc87551d54ffc88e4eeb47d4 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Wed, 19 Aug 2026 09:46:26 +0200 Subject: [PATCH 13/16] [pattern-gen] Add hasSideEffects var --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index f5f8323113dd..cce90cb6d73e 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -94,6 +94,7 @@ struct PatternArg { static CDSLInstr const *CurInstr = nullptr; static SmallVector PatternArgs; +static bool HasSideEffects = 0; // TODO: get from parser attrs static bool MayLoad = 0; static bool MayStore = 0; @@ -1448,8 +1449,8 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { auto &OutStream = *PatternGenArgs::OutStream; - OutStream << "let hasSideEffects = 0, mayLoad = " + - std::to_string((int)MayLoad) + + OutStream << "let hasSideEffects = " + std::to_string((int)HasSideEffects) + + ", mayLoad = " + std::to_string((int)MayLoad) + ", mayStore = " + std::to_string((int)MayStore) + ", " "isCodeGenOnly = 1"; From c4cdfd3103797c9ebb23010d6dd73e0e533723e4 Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Wed, 19 Aug 2026 09:47:25 +0200 Subject: [PATCH 14/16] [pattern-gen] use CurInstr->llvm_instr for output --- llvm/lib/CodeGen/GlobalISel/PatternGen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp index cce90cb6d73e..48c0e301f253 100644 --- a/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp +++ b/llvm/lib/CodeGen/GlobalISel/PatternGen.cpp @@ -1365,7 +1365,6 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { } std::string InstName = MF.getName().str().substr(4); - std::string InstNameO = InstName; ++PatternGenNumInstructionsProcessed; { auto It = std::find_if( @@ -1376,6 +1375,9 @@ bool PatternGen::runOnMachineFunction(MachineFunction &MF) { CurInstr = It.base(); } std::string InstMnemonic = CurInstr->mnemonic; + std::string LLVMInstr = CurInstr->llvm_instr; + std::string InstNameO = LLVMInstr.empty() ? InstName : LLVMInstr; + // We use the PatternArgs vector to store additional information // about parameters that may be found during pattern gen. From 902072e5cc4cf8122b098c87ea47e111b71f7bcd Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Wed, 19 Aug 2026 09:52:56 +0200 Subject: [PATCH 15/16] [pattern-gen] use instr.llvm_instr in InstrFormat --- llvm/tools/pattern-gen/lib/InstrInfo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/tools/pattern-gen/lib/InstrInfo.cpp b/llvm/tools/pattern-gen/lib/InstrInfo.cpp index 0be806004c12..751efe83507a 100644 --- a/llvm/tools/pattern-gen/lib/InstrInfo.cpp +++ b/llvm/tools/pattern-gen/lib/InstrInfo.cpp @@ -8,8 +8,10 @@ std::string EncodingToTablgen(CDSLInstr const& instr) uint8_t size = instr.size; std::string base = (size == 48 ? "RVInst48" : (size == 16 ? "RVInst16" : "RVInst")); + std::string LLVMInstr = instr.llvm_instr; + std::string InstNameO = LLVMInstr.empty() ? instr.name : LLVMInstr; - s << "class RVInst_" << instr.name << "" + s << "class RVInst_" << InstNameO << "" << " : " << base << " {\n"; for (auto const& f : instr.fields) From 2f63e48e7922b58ea4b2b4130e9972e64fb39bbb Mon Sep 17 00:00:00 2001 From: Philipp van Kempen Date: Wed, 19 Aug 2026 12:19:01 +0200 Subject: [PATCH 16/16] core_descs: update check lines to include mnemonic --- core_descs/Example.core_desc | 16 ++++++++-------- core_descs/ExampleMemory.core_desc | 6 +++--- core_descs/ExampleRV32.core_desc | 16 ++++++++-------- core_descs/ExampleRV32K.core_desc | 10 +++++----- core_descs/ExampleRV64.core_desc | 24 ++++++++++++------------ core_descs/ExampleXCV.core_desc | 8 ++++---- core_descs/SelectTests.core_desc | 24 ++++++++++++------------ 7 files changed, 52 insertions(+), 52 deletions(-) diff --git a/core_descs/Example.core_desc b/core_descs/Example.core_desc index af22190cd6bc..d09bc3a3f8af 100644 --- a/core_descs/Example.core_desc +++ b/core_descs/Example.core_desc @@ -7,8 +7,8 @@ InstructionSet XExample extends RISCVBase { instructions { - // CHECK-RV32: Pattern for CV_SUBINCACC: (add (sub (add GPR:$rs1, (i32 1)), GPR:$rs2), GPR:$rd) - // CHECK-RV64: Pattern for CV_SUBINCACC: (add (sub (add GPR:$rs1, (i64 1)), GPR:$rs2), GPR:$rd) + // CHECK-RV32: Pattern for CV_SUBINCACC [cv.subincacc]: (add (sub (add GPR:$rs1, (i32 1)), GPR:$rs2), GPR:$rd) + // CHECK-RV64: Pattern for CV_SUBINCACC [cv.subincacc]: (add (sub (add GPR:$rs1, (i64 1)), GPR:$rs2), GPR:$rd) CV_SUBINCACC { encoding: 7'b0101000 :: rs2[4:0] :: rs1[4:0] :: 3'b011 :: rd[4:0] :: 7'b0101011; assembly: "{name(rd)}, {name(rs1)}, {name(rs2)}"; @@ -19,8 +19,8 @@ InstructionSet XExample extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for CV_MAXU: (select (i32 (setcc (i32 GPR:$rs1), (i32 GPR:$rs2), SETUGT)), GPR:$rs1, GPR:$rs2) - // CHECK-RV64-NEXT: Pattern for CV_MAXU: (select (i64 (setcc (i64 GPR:$rs1), (i64 GPR:$rs2), SETUGT)), GPR:$rs1, GPR:$rs2) + // CHECK-RV32-NEXT: Pattern for CV_MAXU [cv.maxu]: (select (i32 (setcc (i32 GPR:$rs1), (i32 GPR:$rs2), SETUGT)), GPR:$rs1, GPR:$rs2) + // CHECK-RV64-NEXT: Pattern for CV_MAXU [cv.maxu]: (select (i64 (setcc (i64 GPR:$rs1), (i64 GPR:$rs2), SETUGT)), GPR:$rs1, GPR:$rs2) CV_MAXU { encoding: 7'b0101110 :: rs2[4:0] :: rs1[4:0] :: 3'b011 :: rd[4:0] :: 7'b0101011; assembly: "{name(rd)}, {name(rs1)}, {name(rs2)}"; @@ -31,8 +31,8 @@ InstructionSet XExample extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for NAND: (xor (and GPR:$rs2, GPR:$rs1), (i32 -1)) - // CHECK-RV64-NEXT: Pattern for NAND: (xor (and GPR:$rs2, GPR:$rs1), (i64 -1)) + // CHECK-RV32-NEXT: Pattern for NAND [nand]: (xor (and GPR:$rs2, GPR:$rs1), (i32 -1)) + // CHECK-RV64-NEXT: Pattern for NAND [nand]: (xor (and GPR:$rs2, GPR:$rs1), (i64 -1)) NAND { encoding: 7'b0101110 :: rs2[4:0] :: rs1[4:0] :: 3'b011 :: rd[4:0] :: 7'b1101011; assembly: "{name(rd)}, {name(rs1)}, {name(rs2)}"; @@ -43,8 +43,8 @@ InstructionSet XExample extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for ADD3: (add (add GPR:$rs2, GPR:$rs1), GPR:$rd) - // CHECK-RV64-NEXT: Pattern for ADD3: (add (add GPR:$rs2, GPR:$rs1), GPR:$rd) + // CHECK-RV32-NEXT: Pattern for ADD3 [add3]: (add (add GPR:$rs2, GPR:$rs1), GPR:$rd) + // CHECK-RV64-NEXT: Pattern for ADD3 [add3]: (add (add GPR:$rs2, GPR:$rs1), GPR:$rd) ADD3 { encoding: 7'b1 :: rs2[4:0] :: rs1[4:0] :: 3'b010 :: rd[4:0] :: 7'b0000011; assembly:"{name(rd)}, {name(rs2)}({name(rs1)})"; diff --git a/core_descs/ExampleMemory.core_desc b/core_descs/ExampleMemory.core_desc index 2fd46189ea9d..afc44d581af0 100644 --- a/core_descs/ExampleMemory.core_desc +++ b/core_descs/ExampleMemory.core_desc @@ -2,7 +2,7 @@ // RUN: pattern-gen %s -O 3 --no-extend --mattr=+m --riscv-xlen 64 | FileCheck --check-prefixes=CHECK-RV64,CHECK-RV64-NOEXTED -allow-unused-prefixes %s -// CHECK-RV64: Pattern for LDR: (i64 (load (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 (shl (i64 GPR:$rs2), (i64 (i64 uimm5:$imm))))))))) +// CHECK-RV64: Pattern for LDR [ldr]: (i64 (load (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 (shl (i64 GPR:$rs2), (i64 (i64 uimm5:$imm))))))))) LDR { encoding: 2'b0 :: imm[4:0] :: rs2[4:0] :: rs1[4:0] :: 3'b010 :: rd[4:0] :: 7'b0000011; assembly:"{name(rd)}, {imm} {name(rs2)}({name(rs1)})"; @@ -13,7 +13,7 @@ LDR { } } -// CHECK-RV64: Pattern for STR: (store (XLenVT GPR:$rs3), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 (shl (i64 GPR:$rs2), (i64 (i64 uimm5:$imm)))))))) +// CHECK-RV64: Pattern for STR [str]: (store (XLenVT GPR:$rs3), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 (shl (i64 GPR:$rs2), (i64 (i64 uimm5:$imm)))))))) STR { encoding: 2'b1 :: rs3[4:0] :: rs2[4:0] :: rs1[4:0] :: 3'b010 :: imm[4:0] :: 7'b0000011; assembly:"{name(rs3)}, {imm} {name(rs2)}({name(rs1)})"; @@ -23,7 +23,7 @@ STR { } } -// CHECK-RV64: Pattern for LOADMAC: (add GPR:$rd, (mul (i64 (load GPR:$rs2)), (i64 (load GPR:$rs1)))) +// CHECK-RV64: Pattern for LOADMAC [loadmac]: (add GPR:$rd, (mul (i64 (load GPR:$rs2)), (i64 (load GPR:$rs1)))) LOADMAC { encoding: 7'd40 :: rs2[4:0] :: rs1[4:0] :: 3'b010 :: rd[4:0] :: 7'b0000011; assembly:"{name(rd)}, ({name(rs2)}), ({name(rs1)})"; diff --git a/core_descs/ExampleRV32.core_desc b/core_descs/ExampleRV32.core_desc index a52c272a3a9c..d47ffd1e362a 100644 --- a/core_descs/ExampleRV32.core_desc +++ b/core_descs/ExampleRV32.core_desc @@ -5,7 +5,7 @@ InstructionSet XExampleRV32 extends RISCVBase { instructions { - // CHECK-RV32: Pattern for LB: (i32 (sextloadi8 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) + // CHECK-RV32: Pattern for LB [lb]: (i32 (sextloadi8 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) LB { operands: { unsigned<5> rd; @@ -21,7 +21,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for LH: (i32 (sextloadi16 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) + // CHECK-RV32-NEXT: Pattern for LH [lh]: (i32 (sextloadi16 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) LH { operands: { unsigned<5> rd; @@ -37,7 +37,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for LW: (i32 (load (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) + // CHECK-RV32-NEXT: Pattern for LW [lw]: (i32 (load (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) LW { operands: { unsigned<5> rd; @@ -53,7 +53,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for LBU: (i32 (zextloadi8 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) + // CHECK-RV32-NEXT: Pattern for LBU [lbu]: (i32 (zextloadi8 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) LBU { operands: { unsigned<5> rd; @@ -69,7 +69,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for LHU: (i32 (zextloadi16 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) + // CHECK-RV32-NEXT: Pattern for LHU [lhu]: (i32 (zextloadi16 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm)))))) LHU { operands: { unsigned<5> rd; @@ -85,7 +85,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for SB: (truncstorei8 (XLenVT GPR:$rs2), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm))))) + // CHECK-RV32-NEXT: Pattern for SB [sb]: (truncstorei8 (XLenVT GPR:$rs2), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm))))) SB { operands: { unsigned<5> rs1; @@ -100,7 +100,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for SH: (truncstorei16 (XLenVT GPR:$rs2), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm))))) + // CHECK-RV32-NEXT: Pattern for SH [sh]: (truncstorei16 (XLenVT GPR:$rs2), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm))))) SH { operands: { unsigned<5> rs1; @@ -115,7 +115,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for SW: (store (XLenVT GPR:$rs2), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm))))) + // CHECK-RV32-NEXT: Pattern for SW [sw]: (store (XLenVT GPR:$rs2), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i32 (i32 simm12:$imm))))) SW { operands: { unsigned<5> rs1; diff --git a/core_descs/ExampleRV32K.core_desc b/core_descs/ExampleRV32K.core_desc index 5e8db20bf3d6..8c81c6cb190e 100644 --- a/core_descs/ExampleRV32K.core_desc +++ b/core_descs/ExampleRV32K.core_desc @@ -3,7 +3,7 @@ InstructionSet XExampleRV32 extends RISCVBase { instructions { - // CHECK-RV32: Pattern for K_LLI: (i32 uimm32:$imm) + // CHECK-RV32: Pattern for K_LLI [k.lli]: (i32 uimm32:$imm) K_LLI { encoding: 4'b0000 :: imm[31:0] :: rd[4:0] :: 7'b1011111; assembly: {"k.lli", "{name(rd)}, {imm}"}; @@ -14,7 +14,7 @@ InstructionSet XExampleRV32 extends RISCVBase { X[rd] = (unsigned) ((unsigned) imm); } } - // CHECK-RV32: Pattern for K_ADDI: (add GPR:$rs1, (i32 uimm24:$imm)) + // CHECK-RV32: Pattern for K_ADDI [k.addi]: (add GPR:$rs1, (i32 uimm24:$imm)) K_ADDI { encoding: 4'b0001 :: imm[23:0] :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b1011111; assembly: {"k.addi", "{name(rd)}, {name(rs1)}, {imm}"}; @@ -25,7 +25,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } } - // CHECK-RV32: Pattern for K_ANDI: (and GPR:$rs1, (i32 uimm24:$imm)) + // CHECK-RV32: Pattern for K_ANDI [k.andi]: (and GPR:$rs1, (i32 uimm24:$imm)) K_ANDI { encoding: 4'b0001 :: imm[23:0] :: rs1[4:0] :: 3'b001 :: rd[4:0] :: 7'b1011111; assembly: {"k.andi", "{name(rd)}, {name(rs1)}, {imm}"}; @@ -36,7 +36,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } } - // CHECK-RV32: Pattern for K_XORI: (xor GPR:$rs1, (i32 uimm24:$imm)) + // CHECK-RV32: Pattern for K_XORI [k.xori]: (xor GPR:$rs1, (i32 uimm24:$imm)) K_XORI { encoding: 4'b0001 :: imm[23:0] :: rs1[4:0] :: 3'b010 :: rd[4:0] :: 7'b1011111; assembly: {"k.xori", "{name(rd)}, {name(rs1)}, {imm}"}; @@ -47,7 +47,7 @@ InstructionSet XExampleRV32 extends RISCVBase { } } } - // CHECK-RV32: Pattern for K_ORI: (or GPR:$rs1, (i32 uimm24:$imm)) + // CHECK-RV32: Pattern for K_ORI [k.ori]: (or GPR:$rs1, (i32 uimm24:$imm)) K_ORI { encoding: 4'b0001 :: imm[23:0] :: rs1[4:0] :: 3'b011 :: rd[4:0] :: 7'b1011111; assembly: {"k.ori", "{name(rd)}, {name(rs1)}, {imm}"}; diff --git a/core_descs/ExampleRV64.core_desc b/core_descs/ExampleRV64.core_desc index 8c789c8dfe4d..aa15fb56f249 100644 --- a/core_descs/ExampleRV64.core_desc +++ b/core_descs/ExampleRV64.core_desc @@ -13,7 +13,7 @@ InstructionSet XExampleRV64 extends RISCVBase { // X[rd] = (signed<64>)res; // } // } - // CHECK-RV64: Pattern for ADDW2: (i64 (sext (i32 (add (i32 GPR:$rs2), (i32 GPR:$rs1))))) + // CHECK-RV64: Pattern for ADDW2 [addw2]: (i64 (sext (i32 (add (i32 GPR:$rs2), (i32 GPR:$rs1))))) ADDW2 { encoding: 7'b0000000 :: rs2[4:0] :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b0111011; assembly: "{name(rd)}, {name(rs1)}, {name(rs2)}"; @@ -22,7 +22,7 @@ InstructionSet XExampleRV64 extends RISCVBase { X[rd] = (signed<64>)res; } } - // CHECK-RV64-NEXT: Pattern for ADDW3: (i64 (sext (i32 (add (i32 GPR:$rs2), (i32 GPR:$rs1))))) + // CHECK-RV64-NEXT: Pattern for ADDW3 [addw3]: (i64 (sext (i32 (add (i32 GPR:$rs2), (i32 GPR:$rs1))))) ADDW3 { encoding: 7'b0000000 :: rs2[4:0] :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b0111011; assembly: "{name(rd)}, {name(rs1)}, {name(rs2)}"; @@ -32,7 +32,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for LB: (i64 (sextloadi8 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) + // CHECK-RV64-NEXT: Pattern for LB [lb]: (i64 (sextloadi8 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) LB { operands: { unsigned<5> rd; @@ -48,7 +48,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for LH: (i64 (sextloadi16 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) + // CHECK-RV64-NEXT: Pattern for LH [lh]: (i64 (sextloadi16 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) LH { operands: { unsigned<5> rd; @@ -64,7 +64,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for LW: (i64 (sextloadi32 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) + // CHECK-RV64-NEXT: Pattern for LW [lw]: (i64 (sextloadi32 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) LW { operands: { unsigned<5> rd; @@ -80,7 +80,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for LD: (i64 (load (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) + // CHECK-RV64-NEXT: Pattern for LD [ld]: (i64 (load (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) LD { operands: { unsigned<5> rd; @@ -96,7 +96,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for LBU: (i64 (zextloadi8 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) + // CHECK-RV64-NEXT: Pattern for LBU [lbu]: (i64 (zextloadi8 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) LBU { operands: { unsigned<5> rd; @@ -112,7 +112,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for LHU: (i64 (zextloadi16 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) + // CHECK-RV64-NEXT: Pattern for LHU [lhu]: (i64 (zextloadi16 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) LHU { operands: { unsigned<5> rd; @@ -128,7 +128,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for LWU: (i64 (zextloadi32 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) + // CHECK-RV64-NEXT: Pattern for LWU [lwu]: (i64 (zextloadi32 (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm)))))) LWU { operands: { unsigned<5> rd; @@ -144,7 +144,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for SB: (truncstorei8 (XLenVT (i32 (trunc GPR:$rs2))), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm))))) + // CHECK-RV64-NEXT: Pattern for SB [sb]: (truncstorei8 (XLenVT (i32 (trunc GPR:$rs2))), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm))))) SB { operands: { unsigned<5> rs1; @@ -159,7 +159,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for SH: (truncstorei16 (XLenVT (i32 (trunc GPR:$rs2))), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm))))) + // CHECK-RV64-NEXT: Pattern for SH [sh]: (truncstorei16 (XLenVT (i32 (trunc GPR:$rs2))), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm))))) SH { operands: { unsigned<5> rs1; @@ -174,7 +174,7 @@ InstructionSet XExampleRV64 extends RISCVBase { } } - // CHECK-RV64-NEXT: Pattern for SW: (truncstorei32 (XLenVT (i32 (trunc GPR:$rs2))), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm))))) + // CHECK-RV64-NEXT: Pattern for SW [sw]: (truncstorei32 (XLenVT (i32 (trunc GPR:$rs2))), (iPTR (ptradd (iPTR (iPTR GPR:$rs1)), (i64 (i64 simm12:$imm))))) SW { operands: { unsigned<5> rs1; diff --git a/core_descs/ExampleXCV.core_desc b/core_descs/ExampleXCV.core_desc index c9f4419cd285..718fcb565722 100644 --- a/core_descs/ExampleXCV.core_desc +++ b/core_descs/ExampleXCV.core_desc @@ -5,7 +5,7 @@ InstructionSet XExampleCoreV extends RISCVBase { instructions { - // CHECK-RV32: Pattern for CV_MAC: (add (mul GPR:$rs2, GPR:$rs1), GPR:$rd) + // CHECK-RV32: Pattern for CV_MAC [cv.mac]: (add (mul GPR:$rs2, GPR:$rs1), GPR:$rd) CV_MAC { encoding: 7'b1001000 :: rs2[4:0] :: rs1[4:0] :: 3'b011 :: rd[4:0] :: 7'b0101011; assembly: "{name(rd)}, {name(rs1)}, {name(rs2)}"; @@ -15,7 +15,7 @@ InstructionSet XExampleCoreV extends RISCVBase { } } - // CHECK-RV32-NEXT: Pattern for CV_ABS: (xor (add GPR:$rs1, (i32 (sra (i32 GPR:$rs1), (i32 (i32 31))))), (i32 (sra (i32 GPR:$rs1), (i32 (i32 31))))) + // CHECK-RV32-NEXT: Pattern for CV_ABS [cv.abs]: (xor (add GPR:$rs1, (i32 (sra (i32 GPR:$rs1), (i32 (i32 31))))), (i32 (sra (i32 GPR:$rs1), (i32 (i32 31))))) CV_ABS { encoding: 7'b0101000 :: 5'b00000 :: rs1[4:0] :: 3'b011 :: rd[4:0] :: 7'b0101011; assembly: "{name(rd)}, {name(rs1)}"; @@ -26,8 +26,8 @@ InstructionSet XExampleCoreV extends RISCVBase { } } - // CHECK-RV32-EXTEND-NEXT: Pattern for CV_ADDN: (select (i32 (setcc (i32 (i32 uimm5:$Luimm5)), (i32 (i32 0)), SETEQ)), (add GPR:$rs2, GPR:$rs1), (select (i32 (setcc (i32 (i32 uimm5:$Luimm5)), (i32 (i32 32)), SETULT)), (or (i32 (srl (i32 (add GPR:$rs2, GPR:$rs1)), (i32 (i32 uimm5:$Luimm5)))), (i32 (shl (i32 (i32 (sra (i32 (i32 (shl (i32 (add (i32 (setcc (i32 (add GPR:$rs2, GPR:$rs1)), (i32 GPR:$rs1), SETULT)), (i32 0))), (i32 (i32 31))))), (i32 (i32 31))))), (i32 (sub (i32 32), (i32 uimm5:$Luimm5)))))), (i32 (sra (i32 (i32 (sra (i32 (i32 (shl (i32 (add (i32 (setcc (i32 (add GPR:$rs2, GPR:$rs1)), (i32 GPR:$rs1), SETULT)), (i32 0))), (i32 (i32 31))))), (i32 (i32 31))))), (i32 (sub (i32 uimm5:$Luimm5), (i32 32))))))) - // CHECK-RV32-NOEXTEND-NEXT: Pattern for CV_ADDN: (i32 (sra (i32 (add GPR:$rs2, GPR:$rs1)), (i32 (i32 uimm5:$Luimm5)))) + // CHECK-RV32-EXTEND-NEXT: Pattern for CV_ADDN [cv.addn]: (select (i32 (setcc (i32 (i32 uimm5:$Luimm5)), (i32 (i32 0)), SETEQ)), (add GPR:$rs2, GPR:$rs1), (select (i32 (setcc (i32 (i32 uimm5:$Luimm5)), (i32 (i32 32)), SETULT)), (or (i32 (srl (i32 (add GPR:$rs2, GPR:$rs1)), (i32 (i32 uimm5:$Luimm5)))), (i32 (shl (i32 (i32 (sra (i32 (i32 (shl (i32 (add (i32 (setcc (i32 (add GPR:$rs2, GPR:$rs1)), (i32 GPR:$rs1), SETULT)), (i32 0))), (i32 (i32 31))))), (i32 (i32 31))))), (i32 (sub (i32 32), (i32 uimm5:$Luimm5)))))), (i32 (sra (i32 (i32 (sra (i32 (i32 (shl (i32 (add (i32 (setcc (i32 (add GPR:$rs2, GPR:$rs1)), (i32 GPR:$rs1), SETULT)), (i32 0))), (i32 (i32 31))))), (i32 (i32 31))))), (i32 (sub (i32 uimm5:$Luimm5), (i32 32))))))) + // CHECK-RV32-NOEXTEND-NEXT: Pattern for CV_ADDN [cv.addn]: (i32 (sra (i32 (add GPR:$rs2, GPR:$rs1)), (i32 (i32 uimm5:$Luimm5)))) CV_ADDN { encoding: 2'b00 :: Luimm5[4:0] :: rs2[4:0] :: rs1[4:0] :: 3'b010 :: rd[4:0] :: 7'b1011011; assembly: "{name(rd)}, {name(rs1)}, {name(rs2)}, {Luimm5}"; diff --git a/core_descs/SelectTests.core_desc b/core_descs/SelectTests.core_desc index 203349f9c7e6..4325054389b1 100644 --- a/core_descs/SelectTests.core_desc +++ b/core_descs/SelectTests.core_desc @@ -1,8 +1,8 @@ // RUN: pattern-gen %s -O 3 --mattr=+m --riscv-xlen 64 | FileCheck --check-prefixes=CHECK-RV64 -allow-unused-prefixes %s // RUN: pattern-gen %s -O 3 --mattr=+m --riscv-xlen 32 | FileCheck --check-prefixes=CHECK-RV32 -allow-unused-prefixes %s -// CHECK-RV64: Pattern for SEXT_BIT23: (i64 (sra (i64 (i64 (shl (i64 GPR:$rs1), (i64 (i64 40))))), (i64 (i64 63)))) -// CHECK-RV32: Pattern for SEXT_BIT23: (i32 (sra (i32 (i32 (shl (i32 GPR:$rs1), (i32 (i32 8))))), (i32 (i32 31)))) +// CHECK-RV64: Pattern for SEXT_BIT23 [sext.bit23]: (i64 (sra (i64 (i64 (shl (i64 GPR:$rs1), (i64 (i64 40))))), (i64 (i64 63)))) +// CHECK-RV32: Pattern for SEXT_BIT23 [sext.bit23]: (i32 (sra (i32 (i32 (shl (i32 GPR:$rs1), (i32 (i32 8))))), (i32 (i32 31)))) SEXT_BIT23 { encoding: 5'b00000 :: 1'b0 :: 1'b0 :: 5'd0 :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b1111011; assembly: "{name(rd)}, {name(rs1)}"; @@ -14,8 +14,8 @@ SEXT_BIT23 { } -// CHECK-RV64: Pattern for ZEXT_BIT23: (and (i64 (srl (i64 GPR:$rs1), (i64 (i64 23)))), (i64 1)) -// CHECK-RV32: Pattern for ZEXT_BIT23: (and (i32 (srl (i32 GPR:$rs1), (i32 (i32 23)))), (i32 1)) +// CHECK-RV64: Pattern for ZEXT_BIT23 [zext.bit23]: (and (i64 (srl (i64 GPR:$rs1), (i64 (i64 23)))), (i64 1)) +// CHECK-RV32: Pattern for ZEXT_BIT23 [zext.bit23]: (and (i32 (srl (i32 GPR:$rs1), (i32 (i32 23)))), (i32 1)) ZEXT_BIT23 { encoding: 5'b00000 :: 1'b0 :: 1'b0 :: 5'd1 :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b1111011; assembly: "{name(rd)}, {name(rs1)}"; @@ -26,8 +26,8 @@ ZEXT_BIT23 { } } -// CHECK-RV64: Pattern for ZEXT_UNALIGNED_BYTE: (and (i64 (srl (i64 GPR:$rs1), (i64 (i64 11)))), (i64 255)) -// CHECK-RV32: Pattern for ZEXT_UNALIGNED_BYTE: (and (i32 (srl (i32 GPR:$rs1), (i32 (i32 11)))), (i32 255)) +// CHECK-RV64: Pattern for ZEXT_UNALIGNED_BYTE [zext.unaligned.byte]: (and (i64 (srl (i64 GPR:$rs1), (i64 (i64 11)))), (i64 255)) +// CHECK-RV32: Pattern for ZEXT_UNALIGNED_BYTE [zext.unaligned.byte]: (and (i32 (srl (i32 GPR:$rs1), (i32 (i32 11)))), (i32 255)) ZEXT_UNALIGNED_BYTE { encoding: 5'b00000 :: 1'b0 :: 1'b0 :: 5'd2 :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b1111011; assembly: "{name(rd)}, {name(rs1)}"; @@ -38,8 +38,8 @@ ZEXT_UNALIGNED_BYTE { } } -// CHECK-RV64: Pattern for SEXT_UNALIGNED_BYTE: (i64 (sra (i64 (i64 (shl (i64 GPR:$rs1), (i64 (i64 45))))), (i64 (i64 56)))) -// CHECK-RV32: Pattern for SEXT_UNALIGNED_BYTE: (i32 (sra (i32 (i32 (shl (i32 GPR:$rs1), (i32 (i32 13))))), (i32 (i32 24)))) +// CHECK-RV64: Pattern for SEXT_UNALIGNED_BYTE [sext.unaligned.byte]: (i64 (sra (i64 (i64 (shl (i64 GPR:$rs1), (i64 (i64 45))))), (i64 (i64 56)))) +// CHECK-RV32: Pattern for SEXT_UNALIGNED_BYTE [sext.unaligned.byte]: (i32 (sra (i32 (i32 (shl (i32 GPR:$rs1), (i32 (i32 13))))), (i32 (i32 24)))) SEXT_UNALIGNED_BYTE { encoding: 5'b00000 :: 1'b0 :: 1'b0 :: 5'd3 :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b1111011; assembly: "{name(rd)}, {name(rs1)}"; @@ -50,8 +50,8 @@ SEXT_UNALIGNED_BYTE { } } -// CHECK-RV64: Pattern for ZEXT_ALIGNED_WORD: (and (i64 (srl (i64 GPR:$rs1), (i64 (i64 16)))), (i64 65535)) -// CHECK-RV32: Pattern for ZEXT_ALIGNED_WORD: (i32 (srl (i32 GPR:$rs1), (i32 (i32 16)))) +// CHECK-RV64: Pattern for ZEXT_ALIGNED_WORD [zext.aligned.word]: (and (i64 (srl (i64 GPR:$rs1), (i64 (i64 16)))), (i64 65535)) +// CHECK-RV32: Pattern for ZEXT_ALIGNED_WORD [zext.aligned.word]: (i32 (srl (i32 GPR:$rs1), (i32 (i32 16)))) ZEXT_ALIGNED_WORD { encoding: 5'b00000 :: 1'b0 :: 1'b0 :: 5'd4 :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b1111011; assembly: "{name(rd)}, {name(rs1)}"; @@ -62,8 +62,8 @@ ZEXT_ALIGNED_WORD { } } -// CHECK-RV64: Pattern for SEXT_ALIGNED_WORD: (i64 (sra (i64 (i64 (shl (i64 GPR:$rs1), (i64 (i64 32))))), (i64 (i64 48)))) -// CHECK-RV32: Pattern for SEXT_ALIGNED_WORD: (i32 (sra (i32 GPR:$rs1), (i32 (i32 16)))) +// CHECK-RV64: Pattern for SEXT_ALIGNED_WORD [sext.aligned.word]: (i64 (sra (i64 (i64 (shl (i64 GPR:$rs1), (i64 (i64 32))))), (i64 (i64 48)))) +// CHECK-RV32: Pattern for SEXT_ALIGNED_WORD [sext.aligned.word]: (i32 (sra (i32 GPR:$rs1), (i32 (i32 16)))) SEXT_ALIGNED_WORD { encoding: 5'b00000 :: 1'b0 :: 1'b0 :: 5'd5 :: rs1[4:0] :: 3'b000 :: rd[4:0] :: 7'b1111011; assembly: "{name(rd)}, {name(rs1)}";