[clang] [CIR] Auto-generate matchAndRewrite for one-to-one CIR-to-LLVM lowerings (PR #190326)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 3 02:33:33 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Henrich Lauko (xlauko)
<details>
<summary>Changes</summary>
When a CIR op specifies a non-empty `llvmOp` field, the lowering
emitter now generates the `matchAndRewrite` body that converts the
result type and forwards all operands to the corresponding LLVM op.
This removes 27 boilerplate lowering patterns from LowerToLLVM.cpp.
Ops needing custom logic (FMaxNumOp/FMinNumOp for FastmathFlags::nsz)
override `llvmOp = ""` to retain hand-written implementations.
Also fixes llvmOp names (TruncOp -> FTruncOp, FloorOp -> FFloorOp)
and adds a diagnostic rejecting conflicting llvmOp + custom constructor.
---
Full diff: https://github.com/llvm/llvm-project/pull/190326.diff
3 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+6-2)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (-255)
- (modified) clang/utils/TableGen/CIRLoweringEmitter.cpp (+30-5)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 56c7b48afbaf5..3b7b7397f1ee0 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -6330,7 +6330,7 @@ def CIR_TanOp : CIR_UnaryFPToFPBuiltinOp<"tan", "TanOp"> {
}];
}
-def CIR_TruncOp : CIR_UnaryFPToFPBuiltinOp<"trunc", "TruncOp"> {
+def CIR_TruncOp : CIR_UnaryFPToFPBuiltinOp<"trunc", "FTruncOp"> {
let summary = "Truncates floating-point value to integer";
let description = [{
`cir.trunc` truncates a floating-point operand to an integer value
@@ -6379,7 +6379,7 @@ def CIR_AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> {
let assemblyFormat = "$src ( `min_is_poison` $min_is_poison^ )? `:` type($src) attr-dict";
}
-def CIR_FloorOp : CIR_UnaryFPToFPBuiltinOp<"floor", "FloorOp"> {
+def CIR_FloorOp : CIR_UnaryFPToFPBuiltinOp<"floor", "FFloorOp"> {
let summary = "Computes the floating-point floor value";
let description = [{
`cir.floor` computes the floor of a floating-point operand and returns
@@ -6481,6 +6481,8 @@ def CIR_FMaxNumOp : CIR_BinaryFPToFPBuiltinOp<"fmaxnum", "MaxNumOp"> {
`cir.fmaxnum` returns the larger of its two operands. If one operand is
NaN, the other operand is returned.
}];
+ // Needs custom lowering for FastmathFlags::nsz.
+ let llvmOp = "";
}
def CIR_FMaximumOp : CIR_BinaryFPToFPBuiltinOp<"fmaximum", "MaximumOp"> {
@@ -6497,6 +6499,8 @@ def CIR_FMinNumOp : CIR_BinaryFPToFPBuiltinOp<"fminnum", "MinNumOp"> {
`cir.fminnum` returns the smaller of its two operands. If one operand is
NaN, the other operand is returned.
}];
+ // Needs custom lowering for FastmathFlags::nsz.
+ let llvmOp = "";
}
def CIR_FMinimumOp : CIR_BinaryFPToFPBuiltinOp<"fminimum", "MinimumOp"> {
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index b622fa1ef3205..0640fa8634cf3 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -237,130 +237,6 @@ mlir::LogicalResult CIRToLLVMMemSetOpLowering::matchAndRewrite(
return mlir::success();
}
-mlir::LogicalResult CIRToLLVMSqrtOpLowering::matchAndRewrite(
- cir::SqrtOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::SqrtOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMCosOpLowering::matchAndRewrite(
- cir::CosOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::CosOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMExpOpLowering::matchAndRewrite(
- cir::ExpOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::ExpOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMExp2OpLowering::matchAndRewrite(
- cir::Exp2Op op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::Exp2Op>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMLogOpLowering::matchAndRewrite(
- cir::LogOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::LogOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMLog10OpLowering::matchAndRewrite(
- cir::Log10Op op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::Log10Op>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMLog2OpLowering::matchAndRewrite(
- cir::Log2Op op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::Log2Op>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMNearbyintOpLowering::matchAndRewrite(
- cir::NearbyintOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::NearbyintOp>(op, resTy,
- adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMRintOpLowering::matchAndRewrite(
- cir::RintOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::RintOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMRoundOpLowering::matchAndRewrite(
- cir::RoundOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::RoundOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMRoundEvenOpLowering::matchAndRewrite(
- cir::RoundEvenOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::RoundEvenOp>(op, resTy,
- adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMSinOpLowering::matchAndRewrite(
- cir::SinOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::SinOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMTanOpLowering::matchAndRewrite(
- cir::TanOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::TanOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMTruncOpLowering::matchAndRewrite(
- cir::TruncOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::FTruncOp>(op, resTy,
- adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMFloorOpLowering::matchAndRewrite(
- cir::FloorOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::FFloorOp>(op, resTy,
- adaptor.getSrc());
- return mlir::success();
-}
-
static mlir::Value getLLVMIntCast(mlir::ConversionPatternRewriter &rewriter,
mlir::Value llvmSrc, mlir::Type llvmDstIntTy,
bool isUnsigned, uint64_t cirSrcWidth,
@@ -846,23 +722,6 @@ struct ConvertCIRToLLVMPass
StringRef getArgument() const override { return "cir-flat-to-llvm"; }
};
-mlir::LogicalResult CIRToLLVMACosOpLowering::matchAndRewrite(
- cir::ACosOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::ACosOp>(op, resTy,
- adaptor.getOperands()[0]);
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMASinOpLowering::matchAndRewrite(
- cir::ASinOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::ASinOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
mlir::LogicalResult CIRToLLVMIsFPClassOpLowering::matchAndRewrite(
cir::IsFPClassOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
@@ -1722,31 +1581,6 @@ mlir::LogicalResult CIRToLLVMDerivedClassAddrOpLowering::matchAndRewrite(
return mlir::success();
}
-mlir::LogicalResult CIRToLLVMATanOpLowering::matchAndRewrite(
- cir::ATanOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::ATanOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMCeilOpLowering::matchAndRewrite(
- cir::CeilOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::FCeilOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMCopysignOpLowering::matchAndRewrite(
- cir::CopysignOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::CopySignOp>(
- op, resTy, adaptor.getLhs(), adaptor.getRhs());
- return mlir::success();
-}
-
mlir::LogicalResult CIRToLLVMFMaxNumOpLowering::matchAndRewrite(
cir::FMaxNumOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
@@ -1767,86 +1601,6 @@ mlir::LogicalResult CIRToLLVMFMinNumOpLowering::matchAndRewrite(
return mlir::success();
}
-mlir::LogicalResult CIRToLLVMFMaximumOpLowering::matchAndRewrite(
- cir::FMaximumOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::MaximumOp>(
- op, resTy, adaptor.getLhs(), adaptor.getRhs());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMFMinimumOpLowering::matchAndRewrite(
- cir::FMinimumOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::MinimumOp>(
- op, resTy, adaptor.getLhs(), adaptor.getRhs());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMFModOpLowering::matchAndRewrite(
- cir::FModOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::FRemOp>(op, resTy, adaptor.getLhs(),
- adaptor.getRhs());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMPowOpLowering::matchAndRewrite(
- cir::PowOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::PowOp>(op, resTy, adaptor.getLhs(),
- adaptor.getRhs());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMATan2OpLowering::matchAndRewrite(
- cir::ATan2Op op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::ATan2Op>(op, resTy, adaptor.getLhs(),
- adaptor.getRhs());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMLroundOpLowering::matchAndRewrite(
- cir::LroundOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::LroundOp>(op, resTy,
- adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMLlroundOpLowering::matchAndRewrite(
- cir::LlroundOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::LlroundOp>(op, resTy,
- adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMLrintOpLowering::matchAndRewrite(
- cir::LrintOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::LrintOp>(op, resTy, adaptor.getSrc());
- return mlir::success();
-}
-
-mlir::LogicalResult CIRToLLVMLlrintOpLowering::matchAndRewrite(
- cir::LlrintOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::LlrintOp>(op, resTy,
- adaptor.getSrc());
- return mlir::success();
-}
-
mlir::LogicalResult CIRToLLVMAllocaOpLowering::matchAndRewrite(
cir::AllocaOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
@@ -2365,15 +2119,6 @@ mlir::LogicalResult CIRToLLVMExpectOpLowering::matchAndRewrite(
return mlir::success();
}
-mlir::LogicalResult CIRToLLVMFAbsOpLowering::matchAndRewrite(
- cir::FAbsOp op, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const {
- mlir::Type resTy = typeConverter->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::FAbsOp>(op, resTy,
- adaptor.getOperands()[0]);
- return mlir::success();
-}
-
mlir::LogicalResult CIRToLLVMAbsOpLowering::matchAndRewrite(
cir::AbsOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/utils/TableGen/CIRLoweringEmitter.cpp b/clang/utils/TableGen/CIRLoweringEmitter.cpp
index 36417b6df8369..7051e1fb57044 100644
--- a/clang/utils/TableGen/CIRLoweringEmitter.cpp
+++ b/clang/utils/TableGen/CIRLoweringEmitter.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "TableGenBackends.h"
+#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <string>
@@ -133,7 +134,8 @@ void GenerateABILoweringPattern(llvm::StringRef OpName,
void GenerateLLVMLoweringPattern(llvm::StringRef OpName,
llvm::StringRef PatternName, bool IsRecursive,
llvm::StringRef ExtraDecl,
- const Record *CustomCtorRec) {
+ const Record *CustomCtorRec,
+ llvm::StringRef LLVMOp) {
std::optional<CustomLoweringCtor> CustomCtor =
parseCustomLoweringCtor(CustomCtorRec);
std::string CodeBuffer;
@@ -177,9 +179,24 @@ void GenerateLLVMLoweringPattern(llvm::StringRef OpName,
Code << " }\n\n";
- Code << " mlir::LogicalResult matchAndRewrite(cir::" << OpName
- << " op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) "
- "const override;\n";
+ if (!LLVMOp.empty()) {
+ // Generate the matchAndRewrite body automatically.
+ Code
+ << " 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";
+ Code << " return mlir::success();\n";
+ Code << " }\n";
+ } else {
+ Code
+ << " mlir::LogicalResult matchAndRewrite(cir::" << OpName
+ << " op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) "
+ "const override;\n";
+ }
if (!ExtraDecl.empty()) {
Code << "\nprivate:\n";
@@ -208,8 +225,16 @@ void Generate(const Record *OpRecord) {
llvm::StringRef ExtraDecl =
OpRecord->getValueAsString("extraLLVMLoweringPatternDecl");
+ llvm::StringRef LLVMOp = OpRecord->getValueAsString("llvmOp");
+
+ if (!LLVMOp.empty() && CustomCtor)
+ PrintFatalError(OpRecord->getLoc(),
+ "op '" + OpName +
+ "' has both llvmOp and a custom lowering "
+ "constructor, which is not supported");
+
GenerateLLVMLoweringPattern(OpName, PatternName, IsRecursive, ExtraDecl,
- CustomCtor);
+ CustomCtor, LLVMOp);
// 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/190326
More information about the cfe-commits
mailing list