Skip to content
Open
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
38 changes: 38 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -3043,6 +3043,44 @@ def CIR_ArrayDtor : CIR_ArrayInitDestroy<"array.dtor"> {
}];
}

//===----------------------------------------------------------------------===//
// IsConstantOp
//===----------------------------------------------------------------------===//

def CIR_IsConstantOp : CIR_Op<"is_constant", [Pure]> {
let summary = "Check if a value is a compile-time constant";
let description = [{
The `cir.is_constant` operation checks whether its input value is a
compile-time constant. This operation models the `__builtin_constant_p`
builtin function.

The operation takes a single operand of any CIR type and returns a signed
32-bit integer. The result is 1 if the operand is a compile-time constant,
and 0 otherwise.
Comment on lines +3057 to +3059
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not true, the expected result is bool


If the value can be determined to be constant at compile time, this
operation may be folded to a constant value. Otherwise, it will be lowered
to the `llvm.is.constant` intrinsic.

Example:

```mlir
%0 = cir.is_constant %expr : i32 -> !s32i
%1 = cir.is_constant %ptr : !cir.ptr<i32> -> !s32i
Comment on lines +3068 to +3069
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
%0 = cir.is_constant %expr : i32 -> !s32i
%1 = cir.is_constant %ptr : !cir.ptr<i32> -> !s32i
%0 = cir.is_constant %expr : i32 -> !cir.bool
%1 = cir.is_constant %ptr : !cir.ptr<i32> -> !cir.bool

```
}];

let arguments = (ins CIR_AnyType:$value);
let results = (outs CIR_BoolType:$result);

let assemblyFormat = [{
`(` $value `:` type($value) `)` `:` type($result) attr-dict
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`(` $value `:` type($value) `)` `:` type($result) attr-dict
`(` $value `:` qualified(type($value)) `)` `->` qualified(type($result)) attr-dict

}];

// let hasFolder = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this or implement folder as well.

// let hasLLVMLowering = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commented out?

}

//===----------------------------------------------------------------------===//
// VecCreate
//===----------------------------------------------------------------------===//
Expand Down
37 changes: 37 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,43 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return RValue::get(
builder.createBitcast(allocaAddr, builder.getVoidPtrTy()));
}

case Builtin::BI__builtin_constant_p: {
mlir::Location loc = getLoc(e->getSourceRange());
mlir::Type ResultType = convertType(e->getType());

const Expr *Arg = e->getArg(0);
QualType ArgType = Arg->getType();
Comment on lines +207 to +208
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const Expr *Arg = e->getArg(0);
QualType ArgType = Arg->getType();
const Expr *arg = e->getArg(0);
QualType argType = arg->getType();

// FIXME: The allowance for Obj-C pointers and block pointers is historical
// and likely a mistake.
if (!ArgType->isIntegralOrEnumerationType() && !ArgType->isFloatingType() &&
!ArgType->isObjCObjectPointerType() && !ArgType->isBlockPointerType())
// Per the GCC documentation, only numeric constants are recognized after
// inlining.
return RValue::get(
builder.getConstInt(getLoc(e->getSourceRange()),
mlir::cast<cir::IntType>(ResultType), 0));

if (Arg->HasSideEffects(getContext()))
// The argument is unevaluated, so be conservative if it might have
// side-effects.
return RValue::get(
builder.getConstInt(getLoc(e->getSourceRange()),
mlir::cast<cir::IntType>(ResultType), 0));

mlir::Value ArgValue = emitScalarExpr(Arg);
if (ArgType->isObjCObjectPointerType())
// Convert Objective-C objects to id because we cannot distinguish between
// LLVM types for Obj-C classes as they are opaque.
ArgType = cgm.getASTContext().getObjCIdType();
ArgValue = builder.createBitcast(ArgValue, convertType(ArgType));

mlir::Value Result = cir::IsConstantOp::create(
builder, getLoc(e->getSourceRange()), ArgValue);
if (Result.getType() != ResultType)
Result = builder.createBoolToInt(Result, ResultType);
return RValue::get(Result);
Comment on lines +207 to +237
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use lower camelCase for variable names

}

case Builtin::BIcos:
case Builtin::BIcosf:
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2117,6 +2117,25 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) {
return {};
}

//===----------------------------------------------------------------------===//
// IsConstantOp Definitions
//===----------------------------------------------------------------------===//

OpFoldResult cir::IsConstantOp::fold(FoldAdaptor adaptor) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Folder is turned off in the operation, please set hasFolder = 1

// If the input value is a constant attribute, return 1 (true)
mlir::Attribute value = adaptor.getValue();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested this? It doesn't look right.

if (value) {
// The value is a compile-time constant, so return 1
mlir::Type resultType = getResult().getType();
llvm::APInt apInt(32, 1);
llvm::APSInt apSInt(apInt, /*isUnsigned=*/false);
return cir::IntAttr::get(resultType, apSInt);
}

// If the input is not a constant, we cannot fold
return {};
}

//===----------------------------------------------------------------------===//
// CopyOp Definitions
//===----------------------------------------------------------------------===//
Expand Down