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/10] 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/10] 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/10] [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/10] 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/10] [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/10] 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/10] [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/10] 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/10] 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/10] 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.