https://github.com/E00N777 created https://github.com/llvm/llvm-project/pull/202273
### summary This is follow-up to https://github.com/llvm/llvm-project/pull/199599 A CIR op can set the llvmOp field to have cir-tblgen auto-generate its CIR→LLVM lowering instead of using a hand-written pattern.However, the generated body forwards the result type via op.getType(), which only compiles for single-result ops. As a result, ops with zero results could not use this feature. To fix this, teach CIRLoweringEmitter to emit an empty mlir::TypeRange{} for zero-result ops. Then switch cir.lifetime.start and cir.lifetime.end to use llvmOp (dropping their hand-written lowering). The lifetime.cir test covers the generated path. >From f092ccf5c319a1448a8ac776d62baa52593b748d Mon Sep 17 00:00:00 2001 From: E0N777 <[email protected]> Date: Mon, 8 Jun 2026 15:11:04 +0800 Subject: [PATCH] [CIR] Support zero-result ops in clangir TableGen lowering --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 ++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 15 --------------- clang/utils/TableGen/CIRLoweringEmitter.cpp | 19 +++++++++++++------ 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 29644fa35aa74..1e05457775577 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4876,6 +4876,7 @@ def CIR_LifetimeStartOp : CIR_Op<"lifetime.start"> { let arguments = (ins CIR_PointerType:$ptr); let assemblyFormat = "$ptr attr-dict `:` qualified(type($ptr))"; let hasVerifier = 1; + let llvmOp = "LifetimeStartOp"; } def CIR_LifetimeEndOp : CIR_Op<"lifetime.end"> { @@ -4911,6 +4912,7 @@ def CIR_LifetimeEndOp : CIR_Op<"lifetime.end"> { let arguments = (ins CIR_PointerType:$ptr); let assemblyFormat = "$ptr attr-dict `:` qualified(type($ptr))"; let hasVerifier = 1; + let llvmOp = "LifetimeEndOp"; } //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 39ab2dc359958..c7eccd2f19c19 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -4156,21 +4156,6 @@ mlir::LogicalResult CIRToLLVMStackRestoreOpLowering::matchAndRewrite( return mlir::success(); } -mlir::LogicalResult CIRToLLVMLifetimeStartOpLowering::matchAndRewrite( - cir::LifetimeStartOp op, OpAdaptor adaptor, - mlir::ConversionPatternRewriter &rewriter) const { - rewriter.replaceOpWithNewOp<mlir::LLVM::LifetimeStartOp>(op, - adaptor.getPtr()); - return mlir::success(); -} - -mlir::LogicalResult CIRToLLVMLifetimeEndOpLowering::matchAndRewrite( - cir::LifetimeEndOp op, OpAdaptor adaptor, - mlir::ConversionPatternRewriter &rewriter) const { - rewriter.replaceOpWithNewOp<mlir::LLVM::LifetimeEndOp>(op, adaptor.getPtr()); - return mlir::success(); -} - mlir::LogicalResult CIRToLLVMVecCreateOpLowering::matchAndRewrite( cir::VecCreateOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { diff --git a/clang/utils/TableGen/CIRLoweringEmitter.cpp b/clang/utils/TableGen/CIRLoweringEmitter.cpp index d7417ee38875e..dc2151e3f6c09 100644 --- a/clang/utils/TableGen/CIRLoweringEmitter.cpp +++ b/clang/utils/TableGen/CIRLoweringEmitter.cpp @@ -138,7 +138,7 @@ void GenerateLLVMLoweringPattern(llvm::StringRef OpName, llvm::StringRef PatternName, bool IsRecursive, llvm::StringRef ExtraDecl, const Record *CustomCtorRec, - llvm::StringRef LLVMOp) { + llvm::StringRef LLVMOp, bool IsZeroResult) { std::optional<CustomLoweringCtor> CustomCtor = parseCustomLoweringCtor(CustomCtorRec); std::string CodeBuffer; @@ -188,10 +188,15 @@ void GenerateLLVMLoweringPattern(llvm::StringRef OpName, << " mlir::LogicalResult matchAndRewrite(cir::" << OpName << " op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) " "const override {\n"; - Code - << " mlir::Type resTy = typeConverter->convertType(op.getType());\n"; - Code << " rewriter.replaceOpWithNewOp<mlir::LLVM::" << LLVMOp - << ">(op, resTy, adaptor.getOperands());\n"; + if (IsZeroResult) { + Code << " rewriter.replaceOpWithNewOp<mlir::LLVM::" << LLVMOp + << ">(op, mlir::TypeRange{}, adaptor.getOperands());\n"; + } else { + Code + << " mlir::Type resTy = typeConverter->convertType(op.getType());\n"; + Code << " rewriter.replaceOpWithNewOp<mlir::LLVM::" << LLVMOp + << ">(op, resTy, adaptor.getOperands());\n"; + } Code << " return mlir::success();\n"; Code << " }\n"; } else { @@ -236,8 +241,10 @@ void Generate(const Record *OpRecord) { "' has both llvmOp and a custom lowering " "constructor, which is not supported"); + const DagInit *ResultsDag = OpRecord->getValueAsDag("results"); + bool IsZeroResult = ResultsDag->getNumArgs() == 0; GenerateLLVMLoweringPattern(OpName, PatternName, IsRecursive, ExtraDecl, - CustomCtor, LLVMOp); + CustomCtor, LLVMOp, IsZeroResult); // Only automatically register patterns that use the default constructor. // Patterns with a custom constructor must be manually registered by the // lowering pass. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
