llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangir Author: Sathwik Kodamarthi (siddu0660) <details> <summary>Changes</summary> --- Full diff: https://github.com/llvm/llvm-project/pull/166832.diff 3 Files Affected: - (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+38) - (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+25) - (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+19) ``````````diff diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 2b361ed0982c6..9765684a1cd72 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4052,6 +4052,44 @@ def CIR_ExpectOp : CIR_Op<"expect", [ }]; } +//===----------------------------------------------------------------------===// +// 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. + + 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 + ``` + }]; + + let arguments = (ins CIR_AnyType:$value); + let results = (outs CIR_SInt32:$result); + + let assemblyFormat = [{ + $value `:` type($value) `->` type($result) attr-dict + }]; + + let hasFolder = 1; + let hasLLVMLowering = false; +} + //===----------------------------------------------------------------------===// // PrefetchOp //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index e35100ffe4b6b..8777ff16f068f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -199,6 +199,31 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, return RValue::get( builder.createBitcast(allocaAddr, builder.getVoidPtrTy())); } + + case Builtin::BI__builtin_constant_p: { + auto loc = getLoc(e->getSourceRange()); + + Expr::EvalResult evalResult; + + // Try to evaluate at compile time first + if (e->getArg(0)->EvaluateAsRValue(evalResult, getContext()) && + !evalResult.hasSideEffects()) { + // Expression is a compile-time constant, return 1 + llvm::APInt apInt(32, 1); + llvm::APSInt apSInt(apInt, /*isUnsigned=*/false); + return RValue::get(builder.getConstInt(loc, apSInt)); + } + + // Expression cannot be evaluated at compile time, emit runtime check + mlir::Value argValue = emitScalarExpr(e->getArg(0)); + mlir::Type resultType = builder.getSInt32Ty(); + auto isConstantOp = cir::IsConstantOp::create(builder, loc, resultType, argValue); + mlir::Value resultValue = isConstantOp.getResult(); + mlir::Type exprTy = convertType(e->getType()); + if (exprTy != resultValue.getType()) + resultValue = builder.createIntCast(resultValue, exprTy); + return RValue::get(resultValue); + } case Builtin::BIcos: case Builtin::BIcosf: diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 7ba03ce40140c..de23514cf5a79 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2117,6 +2117,25 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) { return {}; } +//===----------------------------------------------------------------------===// +// IsConstantOp Definitions +//===----------------------------------------------------------------------===// + +OpFoldResult cir::IsConstantOp::fold(FoldAdaptor adaptor) { + // If the input value is a constant attribute, return 1 (true) + mlir::Attribute value = adaptor.getValue(); + 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 //===----------------------------------------------------------------------===// `````````` </details> https://github.com/llvm/llvm-project/pull/166832 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
