Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
38 changes: 38 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//

#include "CIRGenCall.h"
#include "CIRGenConstantEmitter.h"
#include "CIRGenFunction.h"
#include "CIRGenModule.h"
#include "CIRGenValue.h"
Expand Down Expand Up @@ -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());
}
Expand All @@ -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 {};
}
4 changes: 4 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -1811,6 +1819,7 @@ void ConvertCIRToLLVMPass::runOnOperation() {
dl);
patterns.add<
// clang-format off
CIRToLLVMAssumeOpLowering,
CIRToLLVMBaseClassAddrOpLowering,
CIRToLLVMBinOpLowering,
CIRToLLVMBrCondOpLowering,
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
16 changes: 16 additions & 0 deletions clang/test/CIR/CodeGen/builtin_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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: }