Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR][CIRGen] Add CIRGen support for assume statement #1205

Merged
merged 1 commit into from
Dec 6, 2024
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
11 changes: 10 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
if (E->getArg(0)->HasSideEffects(getContext()))
return RValue::get(nullptr);

mlir::Value argValue = emitScalarExpr(E->getArg(0));
mlir::Value argValue = emitCheckedArgForAssume(E->getArg(0));
builder.create<cir::AssumeOp>(getLoc(E->getExprLoc()), argValue);
return RValue::get(nullptr);
}
Expand Down Expand Up @@ -2478,6 +2478,15 @@ mlir::Value CIRGenFunction::emitCheckedArgForBuiltin(const Expr *E,
llvm_unreachable("NYI");
}

mlir::Value CIRGenFunction::emitCheckedArgForAssume(const Expr *E) {
mlir::Value argValue = evaluateExprAsBool(E);
if (!SanOpts.has(SanitizerKind::Builtin))
return argValue;

assert(!MissingFeatures::sanitizerBuiltin());
llvm_unreachable("NYI");
}

static mlir::Value emitTargetArchBuiltinExpr(CIRGenFunction *CGF,
unsigned BuiltinID,
const CallExpr *E,
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1782,6 +1782,10 @@ class CIRGenFunction : public CIRGenTypeCache {
/// enabled, a runtime check specified by \p Kind is also emitted.
mlir::Value emitCheckedArgForBuiltin(const Expr *E, BuiltinCheckKind Kind);

/// 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);

/// returns true if aggregate type has a volatile member.
/// TODO(cir): this could be a common AST helper between LLVM / CIR.
bool hasVolatileMember(QualType T) {
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,16 @@ CIRGenFunction::emitAttributedStmt(const AttributedStmt &S) {
case attr::AlwaysInline:
case attr::MustTail:
llvm_unreachable("NIY attributes");
case attr::CXXAssume: {
const Expr *assumption = cast<CXXAssumeAttr>(A)->getAssumption();
if (getLangOpts().CXXAssumptions && builder.getInsertionBlock() &&
!assumption->HasSideEffects(getContext())) {
mlir::Value assumptionValue = emitCheckedArgForAssume(assumption);
builder.create<cir::AssumeOp>(getLoc(S.getSourceRange()),
assumptionValue);
}
break;
}
default:
break;
}
Expand Down
20 changes: 18 additions & 2 deletions clang/test/CIR/CodeGen/builtin-assume.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++23 -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck %s --check-prefix=CIR --input-file=%t.cir
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++23 -fclangir -emit-llvm %s -o %t.ll
// RUN: FileCheck %s --check-prefix=LLVM --input-file=%t.ll

int test_assume(int x) {
Expand All @@ -19,6 +19,22 @@ int test_assume(int x) {
// LLVM: %[[#cond:]] = trunc i8 %{{.+}} to i1
// LLVM-NEXT: call void @llvm.assume(i1 %[[#cond]])

int test_assume_attr(int x) {
[[assume(x > 0)]];
return x;
}

// CIR: cir.func @_Z16test_assume_attri
// CIR: %[[#x:]] = cir.load %{{.+}} : !cir.ptr<!s32i>, !s32i
// CIR-NEXT: %[[#zero:]] = cir.const #cir.int<0> : !s32i
// CIR-NEXT: %[[#cond:]] = cir.cmp(gt, %[[#x]], %[[#zero]]) : !s32i, !cir.bool
// CIR-NEXT: cir.assume %[[#cond]] : !cir.bool
// CIR: }

// LLVM: @_Z16test_assume_attri
// LLVM: %[[#cond:]] = trunc i8 %{{.+}} to i1
// LLVM-NEXT: call void @llvm.assume(i1 %[[#cond]])

int test_assume_aligned(int *ptr) {
int *aligned = (int *)__builtin_assume_aligned(ptr, 8);
return *aligned;
Expand Down
Loading