================
@@ -542,6 +542,45 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl
&gd, unsigned builtinID,
return emitCall(e->getCallee()->getType(), CIRGenCallee::forDirect(fnOp),
e,
returnValue);
}
+
+ case Builtin::BI__builtin_constant_p: {
+ mlir::Type resultType = convertType(e->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()) {
+ cgm.errorNYI(e->getSourceRange(),
+ "__builtin_constant_p: Obj-C object pointer");
+ return {};
+ }
+ argValue = builder.createBitcast(argValue, convertType(argType));
+
+ mlir::Value result = cir::IsConstantOp::create(
+ builder, getLoc(e->getSourceRange()), argValue);
+ if (result.getType() != resultType)
----------------
andykaylor wrote:
I think you're right. This was following the behavior of classic codegen, which
does the same check on the result type of the `llvm.is.constant` intrinsic,
which always returns `i1` so that will also always be true.
https://github.com/llvm/llvm-project/pull/170354
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits