[clang] [CIR] Support zero-result ops in clangir TableGen lowering (PR #202273)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 8 00:18:52 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Jiahao Guo (E00N777)
<details>
<summary>Changes</summary>
### 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.
---
Full diff: https://github.com/llvm/llvm-project/pull/202273.diff
3 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+2)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (-15)
- (modified) clang/utils/TableGen/CIRLoweringEmitter.cpp (+13-6)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 29644fa35aa740..1e054577755770 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 39ab2dc359958d..c7eccd2f19c197 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 d7417ee38875ea..dc2151e3f6c098 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.
``````````
</details>
https://github.com/llvm/llvm-project/pull/202273
More information about the cfe-commits
mailing list