https://github.com/mmha updated https://github.com/llvm/llvm-project/pull/153698
>From 1de984292efcc907405812ccb02f348e0a36e0af Mon Sep 17 00:00:00 2001 From: Morris Hafner <mhaf...@nvidia.com> Date: Fri, 15 Aug 2025 00:05:14 +0200 Subject: [PATCH 1/3] [CIR] Implement __builtin_return_address and __builtin_frame_address This adds ReturnAddrOp and FrameAddrOp that represent __builtin_return_address and __builtin_frame_address and the respective lowering to LLVM parts. --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 61 +++++++++++++++++++ clang/lib/CIR/CodeGen/CIRGenBuilder.h | 3 + clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 14 +++++ clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h | 6 +- clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 36 +++++++++++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 40 ++++++++++++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h | 20 ++++++ clang/test/CIR/CodeGen/builtins.cpp | 28 +++++++++ 8 files changed, 206 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index a77e9199cdc96..20a75d52777c6 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2210,6 +2210,67 @@ def CIR_CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> { ]; } +//===----------------------------------------------------------------------===// +// ReturnAddrOp and FrameAddrOp +//===----------------------------------------------------------------------===// + +class CIR_FuncAddrBuiltinOp<string mnemonic> : CIR_Op<mnemonic, []> { + let arguments = (ins CIR_UInt32:$level); + let results = (outs CIR_VoidPtrType:$result); + let assemblyFormat = [{ + `(` $level `)` attr-dict + }]; +} + +def CIR_ReturnAddrOp : CIR_FuncAddrBuiltinOp<"return_address"> { + let summary = + "The return address of the current function, or of one of its callers"; + + let description = [{ + Represents call to builtin function ` __builtin_return_address` in CIR. + This builtin function returns the return address of the current function, + or of one of its callers. + The `level` argument is number of frames to scan up the call stack. + For instance, value of 0 yields the return address of the current function, + value of 1 yields the return address of the caller of the current function, + and so forth. + + Examples: + + ```mlir + %p = return_address(%level) -> !cir.ptr<!void> + ``` + }]; +} + +def CIR_FrameAddrOp : CIR_FuncAddrBuiltinOp<"frame_address"> { + let summary = + "The frame address of the current function, or of one of its callers"; + + let description = [{ + Represents call to builtin function ` __builtin_frame_address` in CIR. + This builtin function returns the frame address of the current function, + or of one of its callers. The frame is the area on the stack that holds + local variables and saved registers. The frame address is normally the + address of the first word pushed on to the stack by the function. + However, the exact definition depends upon the processor and the calling + convention. If the processor has a dedicated frame pointer register, and + the function has a frame, then __builtin_frame_address returns the value of + the frame pointer register. + + The `level` argument is number of frames to scan up the call stack. + For instance, value of 0 yields the frame address of the current function, + value of 1 yields the frame address of the caller of the current function, + and so forth. + + Examples: + + ```mlir + %p = frame_address(%level) -> !cir.ptr<!void> + ``` + }]; +} + //===----------------------------------------------------------------------===// // StackSaveOp & StackRestoreOp //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 8b2538c941f47..a3ff7c58f76ba 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -262,6 +262,9 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { cir::ConstantOp getSInt32(int32_t c, mlir::Location loc) { return getConstantInt(loc, getSInt32Ty(), c); } + cir::ConstantOp getUInt32(uint32_t c, mlir::Location loc) { + return getConstantInt(loc, getUInt32Ty(), c); + } // Creates constant nullptr for pointer type ty. cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) { diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 36aea4c1d39ce..d5f930608cd39 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -312,6 +312,20 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, case Builtin::BI__builtin_rotateright64: return emitRotate(e, /*isRotateLeft=*/false); + case Builtin::BI__builtin_return_address: + case Builtin::BI__builtin_frame_address: { + mlir::Location loc = getLoc(e->getExprLoc()); + mlir::Attribute levelAttr = ConstantEmitter(*this).emitAbstract( + e->getArg(0), e->getArg(0)->getType()); + uint64_t level = mlir::cast<cir::IntAttr>(levelAttr).getUInt(); + if (builtinID == Builtin::BI__builtin_return_address) { + return RValue::get(builder.create<cir::ReturnAddrOp>( + loc, builder.getUInt32(level, loc))); + } + return RValue::get( + builder.create<cir::FrameAddrOp>(loc, builder.getUInt32(level, loc))); + } + case Builtin::BI__builtin_trap: emitTrap(loc, /*createNewBlock=*/true); return RValue::get(nullptr); diff --git a/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h b/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h index d6dac50bb1263..d455f6e283406 100644 --- a/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h +++ b/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h @@ -80,7 +80,7 @@ class ConstantEmitter { // initializer or to propagate to another context; for example, // side effects, or emitting an initialization that requires a // reference to its current location. - mlir::Attribute emitForMemory(mlir::Attribute c, QualType t); + mlir::Attribute emitForMemory(mlir::Attribute c, QualType destType); /// Try to emit the initializer of the given declaration as an abstract /// constant. @@ -90,8 +90,9 @@ class ConstantEmitter { /// asserting that it succeeded. This is only safe to do when the /// expression is known to be a constant expression with either a fairly /// simple type or a known simple form. + mlir::Attribute emitAbstract(const Expr *e, QualType destType); mlir::Attribute emitAbstract(SourceLocation loc, const APValue &value, - QualType t); + QualType destType); mlir::Attribute tryEmitConstantExpr(const ConstantExpr *ce); @@ -101,6 +102,7 @@ class ConstantEmitter { mlir::Attribute tryEmitPrivateForVarInit(const VarDecl &d); + mlir::TypedAttr tryEmitPrivate(const Expr *e, QualType destType); mlir::Attribute tryEmitPrivate(const APValue &value, QualType destType); mlir::Attribute tryEmitPrivateForMemory(const APValue &value, QualType t); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 87ea34df6be59..b0349e008d102 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -700,6 +700,16 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForMemory(const APValue &value, return (c ? emitForMemory(c, destType) : nullptr); } +mlir::Attribute ConstantEmitter::emitAbstract(const Expr *e, + QualType destType) { + AbstractStateRAII state{*this, true}; + mlir::Attribute c = mlir::cast<mlir::Attribute>(tryEmitPrivate(e, destType)); + if (!c) + cgm.errorNYI(e->getSourceRange(), + "emitAbstract failed, emit null constaant"); + return c; +} + mlir::Attribute ConstantEmitter::emitAbstract(SourceLocation loc, const APValue &value, QualType destType) { @@ -721,6 +731,32 @@ mlir::Attribute ConstantEmitter::emitForMemory(mlir::Attribute c, return c; } +mlir::TypedAttr ConstantEmitter::tryEmitPrivate(const Expr *e, + QualType destType) { + assert(!destType->isVoidType() && "can't emit a void constant"); + + if (mlir::Attribute c = + ConstExprEmitter(*this).Visit(const_cast<Expr *>(e), destType)) + return llvm::dyn_cast<mlir::TypedAttr>(c); + + Expr::EvalResult result; + + bool success = false; + + if (destType->isReferenceType()) + success = e->EvaluateAsLValue(result, cgm.getASTContext()); + else + success = + e->EvaluateAsRValue(result, cgm.getASTContext(), inConstantContext); + + if (success && !result.hasSideEffects()) { + mlir::Attribute c = tryEmitPrivate(result.Val, destType); + return llvm::dyn_cast<mlir::TypedAttr>(c); + } + + return nullptr; +} + mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value, QualType destType) { auto &builder = cgm.getBuilder(); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 20b8787d4f55f..86714c07ff701 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -267,6 +267,26 @@ void convertSideEffectForCall(mlir::Operation *callOp, bool isNothrow, } } +static mlir::LLVM::CallIntrinsicOp +createCallLLVMIntrinsicOp(mlir::ConversionPatternRewriter &rewriter, + mlir::Location loc, const llvm::Twine &intrinsicName, + mlir::Type resultTy, mlir::ValueRange operands) { + auto intrinsicNameAttr = + mlir::StringAttr::get(rewriter.getContext(), intrinsicName); + return rewriter.create<mlir::LLVM::CallIntrinsicOp>( + loc, resultTy, intrinsicNameAttr, operands); +} + +static mlir::LLVM::CallIntrinsicOp replaceOpWithCallLLVMIntrinsicOp( + mlir::ConversionPatternRewriter &rewriter, mlir::Operation *op, + const llvm::Twine &intrinsicName, mlir::Type resultTy, + mlir::ValueRange operands) { + mlir::LLVM::CallIntrinsicOp callIntrinOp = createCallLLVMIntrinsicOp( + rewriter, op->getLoc(), intrinsicName, resultTy, operands); + rewriter.replaceOp(op, callIntrinOp.getOperation()); + return callIntrinOp; +} + /// IntAttr visitor. mlir::Value CIRAttrToValue::visitCirAttr(cir::IntAttr intAttr) { mlir::Location loc = parentOp->getLoc(); @@ -1097,6 +1117,24 @@ mlir::LogicalResult CIRToLLVMCallOpLowering::matchAndRewrite( getTypeConverter(), op.getCalleeAttr()); } +mlir::LogicalResult CIRToLLVMReturnAddrOpLowering::matchAndRewrite( + cir::ReturnAddrOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext()); + replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm.returnaddress", + llvmPtrTy, adaptor.getOperands()); + return mlir::success(); +} + +mlir::LogicalResult CIRToLLVMFrameAddrOpLowering::matchAndRewrite( + cir::FrameAddrOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext()); + replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm.frameaddress", llvmPtrTy, + adaptor.getOperands()); + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite( cir::LoadOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -2307,10 +2345,12 @@ void ConvertCIRToLLVMPass::runOnOperation() { CIRToLLVMConstantOpLowering, CIRToLLVMExpectOpLowering, CIRToLLVMFAbsOpLowering, + CIRToLLVMFrameAddrOpLowering, CIRToLLVMFuncOpLowering, CIRToLLVMGetBitfieldOpLowering, CIRToLLVMGetGlobalOpLowering, CIRToLLVMGetMemberOpLowering, + CIRToLLVMReturnAddrOpLowering, CIRToLLVMRotateOpLowering, CIRToLLVMSelectOpLowering, CIRToLLVMSetBitfieldOpLowering, diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index e32bf2d1bae0c..740e10897338f 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -209,6 +209,26 @@ class CIRToLLVMCallOpLowering : public mlir::OpConversionPattern<cir::CallOp> { mlir::ConversionPatternRewriter &rewriter) const override; }; +class CIRToLLVMReturnAddrOpLowering + : public mlir::OpConversionPattern<cir::ReturnAddrOp> { +public: + using mlir::OpConversionPattern<cir::ReturnAddrOp>::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::ReturnAddrOp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + +class CIRToLLVMFrameAddrOpLowering + : public mlir::OpConversionPattern<cir::FrameAddrOp> { +public: + using mlir::OpConversionPattern<cir::FrameAddrOp>::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::FrameAddrOp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + class CIRToLLVMAllocaOpLowering : public mlir::OpConversionPattern<cir::AllocaOp> { mlir::DataLayout const &dataLayout; diff --git a/clang/test/CIR/CodeGen/builtins.cpp b/clang/test/CIR/CodeGen/builtins.cpp index 3d43821af4e51..0e434809fe6be 100644 --- a/clang/test/CIR/CodeGen/builtins.cpp +++ b/clang/test/CIR/CodeGen/builtins.cpp @@ -12,3 +12,31 @@ double fabs(double x) { // CIR: {{.*}} = cir.fabs {{.*}} : !cir.double // LLVM: {{.*}} = call double @llvm.fabs.f64(double {{.*}}) // OGCG: {{.*}} = call double @llvm.fabs.f64(double {{.*}}) + +extern "C" void *test_return_address(void) { + return __builtin_return_address(1); + + // CIR-LABEL: test_return_address + // CIR: [[ARG:%.*]] = cir.const #cir.int<1> : !u32i + // CIR: {{%.*}} = cir.return_address([[ARG]]) + + // LLVM-LABEL: @test_return_address + // LLVM: {{%.*}} = call ptr @llvm.returnaddress(i32 1) + + // OGCG-LABEL: @test_return_address + // OGCG: {{%.*}} = call ptr @llvm.returnaddress(i32 1) +} + +extern "C" void *test_frame_address(void) { + return __builtin_frame_address(1); + + // CIR-LABEL: test_frame_address + // CIR: [[ARG:%.*]] = cir.const #cir.int<1> : !u32i + // CIR: {{%.*}} = cir.frame_address([[ARG]]) + + // LLVM-LABEL: @test_frame_address + // LLVM: {{%.*}} = call ptr @llvm.frameaddress.p0(i32 1) + + // OGCG-LABEL: @test_frame_address + // OGCG: {{%.*}} = call ptr @llvm.frameaddress.p0(i32 1) +} >From 6cdebf460808427c0f843fb139d973a622324b03 Mon Sep 17 00:00:00 2001 From: Morris Hafner <m...@users.noreply.github.com> Date: Fri, 15 Aug 2025 01:00:02 +0200 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Andy Kaylor <akay...@nvidia.com> --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 4 ++-- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 4 ++-- clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 20a75d52777c6..681c22c6203e9 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2227,7 +2227,7 @@ def CIR_ReturnAddrOp : CIR_FuncAddrBuiltinOp<"return_address"> { "The return address of the current function, or of one of its callers"; let description = [{ - Represents call to builtin function ` __builtin_return_address` in CIR. + Represents a call to builtin function ` __builtin_return_address` in CIR. This builtin function returns the return address of the current function, or of one of its callers. The `level` argument is number of frames to scan up the call stack. @@ -2248,7 +2248,7 @@ def CIR_FrameAddrOp : CIR_FuncAddrBuiltinOp<"frame_address"> { "The frame address of the current function, or of one of its callers"; let description = [{ - Represents call to builtin function ` __builtin_frame_address` in CIR. + Represents a call to builtin function ` __builtin_frame_address` in CIR. This builtin function returns the frame address of the current function, or of one of its callers. The frame is the area on the stack that holds local variables and saved registers. The frame address is normally the diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index d5f930608cd39..c960ee597f402 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -319,11 +319,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, e->getArg(0), e->getArg(0)->getType()); uint64_t level = mlir::cast<cir::IntAttr>(levelAttr).getUInt(); if (builtinID == Builtin::BI__builtin_return_address) { - return RValue::get(builder.create<cir::ReturnAddrOp>( + return RValue::get(cir::ReturnAddrOp::create(builder, loc, builder.getUInt32(level, loc))); } return RValue::get( - builder.create<cir::FrameAddrOp>(loc, builder.getUInt32(level, loc))); + cir::FrameAddrOp::create(builder, loc, builder.getUInt32(level, loc))); } case Builtin::BI__builtin_trap: diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 86714c07ff701..993a83388268a 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -273,7 +273,7 @@ createCallLLVMIntrinsicOp(mlir::ConversionPatternRewriter &rewriter, mlir::Type resultTy, mlir::ValueRange operands) { auto intrinsicNameAttr = mlir::StringAttr::get(rewriter.getContext(), intrinsicName); - return rewriter.create<mlir::LLVM::CallIntrinsicOp>( + return mlir::LLVM::CallIntrinsicOp::create(rewriter, loc, resultTy, intrinsicNameAttr, operands); } >From 1961fd2175bcacfa4e282784668a3e9af1218f71 Mon Sep 17 00:00:00 2001 From: Morris Hafner <mhaf...@nvidia.com> Date: Fri, 15 Aug 2025 01:11:02 +0200 Subject: [PATCH 3/3] Address review feedback --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 1 + clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 14 +++++++------- .../lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 681c22c6203e9..30f58d6bf8d29 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2230,6 +2230,7 @@ def CIR_ReturnAddrOp : CIR_FuncAddrBuiltinOp<"return_address"> { Represents a call to builtin function ` __builtin_return_address` in CIR. This builtin function returns the return address of the current function, or of one of its callers. + The `level` argument is number of frames to scan up the call stack. For instance, value of 0 yields the return address of the current function, value of 1 yields the return address of the caller of the current function, diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index c960ee597f402..dcd00696f335d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -315,15 +315,15 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, case Builtin::BI__builtin_return_address: case Builtin::BI__builtin_frame_address: { mlir::Location loc = getLoc(e->getExprLoc()); - mlir::Attribute levelAttr = ConstantEmitter(*this).emitAbstract( - e->getArg(0), e->getArg(0)->getType()); - uint64_t level = mlir::cast<cir::IntAttr>(levelAttr).getUInt(); + llvm::APSInt level = e->getArg(0)->EvaluateKnownConstInt(getContext()); if (builtinID == Builtin::BI__builtin_return_address) { - return RValue::get(cir::ReturnAddrOp::create(builder, - loc, builder.getUInt32(level, loc))); + return RValue::get(cir::ReturnAddrOp::create( + builder, loc, + builder.getConstAPInt(loc, builder.getUInt32Ty(), level))); } - return RValue::get( - cir::FrameAddrOp::create(builder, loc, builder.getUInt32(level, loc))); + return RValue::get(cir::FrameAddrOp::create( + builder, loc, + builder.getConstAPInt(loc, builder.getUInt32Ty(), level))); } case Builtin::BI__builtin_trap: diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 993a83388268a..ed51e6a680b42 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -273,8 +273,8 @@ createCallLLVMIntrinsicOp(mlir::ConversionPatternRewriter &rewriter, mlir::Type resultTy, mlir::ValueRange operands) { auto intrinsicNameAttr = mlir::StringAttr::get(rewriter.getContext(), intrinsicName); - return mlir::LLVM::CallIntrinsicOp::create(rewriter, - loc, resultTy, intrinsicNameAttr, operands); + return mlir::LLVM::CallIntrinsicOp::create(rewriter, loc, resultTy, + intrinsicNameAttr, operands); } static mlir::LLVM::CallIntrinsicOp replaceOpWithCallLLVMIntrinsicOp( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits