Author: Sirui Mu Date: 2025-06-18T17:10:29+08:00 New Revision: 8e157fdbb7b4af9f67b139a9f05feaa9b338d3f5
URL: https://github.com/llvm/llvm-project/commit/8e157fdbb7b4af9f67b139a9f05feaa9b338d3f5 DIFF: https://github.com/llvm/llvm-project/commit/8e157fdbb7b4af9f67b139a9f05feaa9b338d3f5.diff LOG: [CIR] Add support for __builtin_assume (#144376) This patch adds support for the `__builtin_assume` builtin function. Added: Modified: clang/include/clang/CIR/Dialect/IR/CIROps.td clang/include/clang/CIR/MissingFeatures.h clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp clang/lib/CIR/CodeGen/CIRGenFunction.h clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h clang/test/CIR/CodeGen/builtin_call.cpp Removed: ################################################################################ diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 8dd1f0ce361d7..4655cebc82ee7 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2387,4 +2387,26 @@ def ComplexCreateOp : CIR_Op<"complex.create", [Pure, SameTypeOperands]> { let hasFolder = 1; } +//===----------------------------------------------------------------------===// +// Assume Operations +//===----------------------------------------------------------------------===// + +def AssumeOp : CIR_Op<"assume"> { + let summary = "Tell the optimizer that a boolean value is true"; + let description = [{ + The `cir.assume` operation takes a single boolean prediate as its only + argument and does not have any results. The operation tells the optimizer + that the predicate is always true. + + This operation corresponds to the `__assume` and the `__builtin_assume` + builtin functions. + }]; + + let arguments = (ins CIR_BoolType:$predicate); + + let assemblyFormat = [{ + $predicate `:` type($predicate) attr-dict + }]; +} + #endif // CLANG_CIR_DIALECT_IR_CIROPS_TD diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 3dc28e6f2e5bf..3d120903dea19 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -237,6 +237,9 @@ struct MissingFeatures { static bool lowerAggregateLoadStore() { return false; } static bool dataLayoutTypeAllocSize() { return false; } static bool asmLabelAttr() { return false; } + static bool builtinCall() { return false; } + static bool builtinCallF128() { return false; } + static bool builtinCallMathErrno() { return false; } // Missing types static bool dataMemberType() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 19fac00ab8736..83825f0835a1e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "CIRGenCall.h" +#include "CIRGenConstantEmitter.h" #include "CIRGenFunction.h" #include "CIRGenModule.h" #include "CIRGenValue.h" @@ -66,6 +67,32 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, return emitLibraryCall(*this, fd, e, cgm.getBuiltinLibFunction(fd, builtinID)); + assert(!cir::MissingFeatures::builtinCallF128()); + + // If the builtin has been declared explicitly with an assembler label, + // disable the specialized emitting below. Ideally we should communicate the + // rename in IR, or at least avoid generating the intrinsic calls that are + // likely to get lowered to the renamed library functions. + unsigned builtinIDIfNoAsmLabel = fd->hasAttr<AsmLabelAttr>() ? 0 : builtinID; + + assert(!cir::MissingFeatures::builtinCallMathErrno()); + assert(!cir::MissingFeatures::builtinCall()); + + switch (builtinIDIfNoAsmLabel) { + default: + break; + + case Builtin::BI__assume: + case Builtin::BI__builtin_assume: { + if (e->getArg(0)->HasSideEffects(getContext())) + return RValue::get(nullptr); + + mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0)); + builder.create<cir::AssumeOp>(getLoc(e->getExprLoc()), argValue); + return RValue::get(nullptr); + } + } + cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call"); return getUndefRValue(e->getType()); } @@ -88,3 +115,14 @@ cir::FuncOp CIRGenModule::getBuiltinLibFunction(const FunctionDecl *fd, mlir::Type type = convertType(fd->getType()); return getOrCreateCIRFunction(name, type, d, /*forVTable=*/false); } + +mlir::Value CIRGenFunction::emitCheckedArgForAssume(const Expr *e) { + mlir::Value argValue = evaluateExprAsBool(e); + if (!sanOpts.has(SanitizerKind::Builtin)) + return argValue; + + assert(!cir::MissingFeatures::sanitizers()); + cgm.errorNYI(e->getSourceRange(), + "emitCheckedArgForAssume: sanitizers are NYI"); + return {}; +} diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index de6ef2a69faf1..6c490a72b2e93 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -772,6 +772,10 @@ class CIRGenFunction : public CIRGenTypeCache { LValue emitCastLValue(const CastExpr *e); + /// Emits an argument for a call to a `__builtin_assume`. If the builtin + /// sanitizer is enabled, a runtime check is also emitted. + mlir::Value emitCheckedArgForAssume(const Expr *e); + LValue emitCompoundAssignmentLValue(const clang::CompoundAssignOperator *e); void emitConstructorBody(FunctionArgList &args); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 6a4e4e4a7df3b..a96501ab2c384 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -407,6 +407,14 @@ struct ConvertCIRToLLVMPass StringRef getArgument() const override { return "cir-flat-to-llvm"; } }; +mlir::LogicalResult CIRToLLVMAssumeOpLowering::matchAndRewrite( + cir::AssumeOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + auto cond = adaptor.getPredicate(); + rewriter.replaceOpWithNewOp<mlir::LLVM::AssumeOp>(op, cond); + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMBrCondOpLowering::matchAndRewrite( cir::BrCondOp brOp, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -1811,6 +1819,7 @@ void ConvertCIRToLLVMPass::runOnOperation() { dl); patterns.add< // clang-format off + CIRToLLVMAssumeOpLowering, CIRToLLVMBaseClassAddrOpLowering, CIRToLLVMBinOpLowering, CIRToLLVMBrCondOpLowering, diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index a809818063547..a80c66ac1abf2 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -29,6 +29,16 @@ mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::Attribute attr, mlir::LLVM::Linkage convertLinkage(cir::GlobalLinkageKind linkage); +class CIRToLLVMAssumeOpLowering + : public mlir::OpConversionPattern<cir::AssumeOp> { +public: + using mlir::OpConversionPattern<cir::AssumeOp>::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::AssumeOp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + class CIRToLLVMBrCondOpLowering : public mlir::OpConversionPattern<cir::BrCondOp> { public: diff --git a/clang/test/CIR/CodeGen/builtin_call.cpp b/clang/test/CIR/CodeGen/builtin_call.cpp index 322c13c8f081a..0a2226a2cc592 100644 --- a/clang/test/CIR/CodeGen/builtin_call.cpp +++ b/clang/test/CIR/CodeGen/builtin_call.cpp @@ -94,3 +94,19 @@ void library_builtins() { // OGCG: define dso_local void @_Z16library_builtinsv() // OGCG: call i32 (ptr, ...) @printf(ptr noundef null) // OGCG: call void @abort() + +void assume(bool arg) { + __builtin_assume(arg); +} + +// CIR: cir.func @_Z6assumeb +// CIR: cir.assume %{{.+}} : !cir.bool +// CIR: } + +// LLVM: define void @_Z6assumeb +// LLVM: call void @llvm.assume(i1 %{{.+}}) +// LLVM: } + +// OGCG: define {{.*}}void @_Z6assumeb +// OGCG: call void @llvm.assume(i1 %{{.+}}) +// OGCG: } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits