[clang] [CIR] Upstream CastOp and scalar conversions (PR #130690)
Morris Hafner via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 12 15:54:48 PDT 2025
================
@@ -121,29 +375,174 @@ mlir::Value CIRGenFunction::emitScalarExpr(const Expr *e) {
return ScalarExprEmitter(*this, builder).Visit(const_cast<Expr *>(e));
}
+[[maybe_unused]] static bool MustVisitNullValue(const Expr *e) {
+ // If a null pointer expression's type is the C++0x nullptr_t, then
+ // it's not necessarily a simple constant and it must be evaluated
+ // for its potential side effects.
+ return e->getType()->isNullPtrType();
+}
+
// Emit code for an explicit or implicit cast. Implicit
// casts have to handle a more broad range of conversions than explicit
// casts, as they handle things like function to ptr-to-function decay
// etc.
mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
- Expr *e = ce->getSubExpr();
+ Expr *subExpr = ce->getSubExpr();
QualType destTy = ce->getType();
CastKind kind = ce->getCastKind();
+ // These cases are generally not written to ignore the result of evaluating
+ // their sub-expressions, so we clear this now.
+ ignoreResultAssign = false;
+
switch (kind) {
+ case clang::CK_Dependent:
+ llvm_unreachable("dependent cast kind in CIR gen!");
+ case clang::CK_BuiltinFnToFnPtr:
+ llvm_unreachable("builtin functions are handled elsewhere");
+
+ case CK_CPointerToObjCPointerCast:
+ case CK_BlockPointerToObjCPointerCast:
+ case CK_AnyPointerToBlockPointerCast:
+ case CK_BitCast: {
+ mlir::Value src = Visit(const_cast<Expr *>(subExpr));
+ mlir::Type dstTy = cgf.convertType(destTy);
+
+ assert(!cir::MissingFeatures::addressSpace());
+
+ if (cgf.sanOpts.has(SanitizerKind::CFIUnrelatedCast))
+ cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(),
+ "sanitizer support");
+
+ if (cgf.cgm.getCodeGenOpts().StrictVTablePointers)
+ cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(),
+ "strict vtable pointers");
+
+ // Update heapallocsite metadata when there is an explicit pointer cast.
+ assert(!cir::MissingFeatures::addHeapAllocSiteMetadata());
+
+ // If Src is a fixed vector and Dst is a scalable vector, and both have the
+ // same element type, use the llvm.vector.insert intrinsic to perform the
+ // bitcast.
+ assert(!cir::MissingFeatures::scalableVectors());
+
+ // If Src is a scalable vector and Dst is a fixed vector, and both have the
+ // same element type, use the llvm.vector.extract intrinsic to perform the
+ // bitcast.
+ assert(!cir::MissingFeatures::scalableVectors());
+
+ // Perform VLAT <-> VLST bitcast through memory.
+ // TODO: since the llvm.experimental.vector.{insert,extract} intrinsics
+ // require the element types of the vectors to be the same, we
+ // need to keep this around for bitcasts between VLAT <-> VLST where
+ // the element types of the vectors are not the same, until we figure
+ // out a better way of doing these casts.
+ assert(!cir::MissingFeatures::scalableVectors());
+
+ return cgf.getBuilder().createBitcast(cgf.getLoc(subExpr->getSourceRange()),
+ src, dstTy);
+ }
+
+ case CK_AtomicToNonAtomic:
+ cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(),
+ "CastExpr: ", ce->getCastKindName());
+ break;
+ case CK_NonAtomicToAtomic:
+ case CK_UserDefinedConversion:
+ return Visit(const_cast<Expr *>(subExpr));
+ case CK_NoOp: {
+ auto v = Visit(const_cast<Expr *>(subExpr));
+ if (v) {
+ // CK_NoOp can model a pointer qualification conversion, which can remove
+ // an array bound and change the IR type.
+ // FIXME: Once pointee types are removed from IR, remove this.
+ mlir::Type t = cgf.convertType(destTy);
+ if (t != v.getType())
+ cgf.getCIRGenModule().errorNYI("pointer qualification conversion");
+ }
+ return v;
+ }
+
+ case CK_NullToPointer: {
+ if (MustVisitNullValue(subExpr))
+ cgf.getCIRGenModule().errorNYI(
+ subExpr->getSourceRange(),
+ "ignored expression on null to pointer cast");
+
+ // Note that DestTy is used as the MLIR type instead of a custom
+ // nullptr type.
+ mlir::Type ty = cgf.convertType(destTy);
+ return builder.getNullPtr(ty, cgf.getLoc(subExpr->getExprLoc()));
+ }
+
case CK_LValueToRValue:
- assert(cgf.getContext().hasSameUnqualifiedType(e->getType(), destTy));
- assert(e->isGLValue() && "lvalue-to-rvalue applied to r-value!");
- return Visit(const_cast<Expr *>(e));
+ assert(cgf.getContext().hasSameUnqualifiedType(subExpr->getType(), destTy));
+ assert(subExpr->isGLValue() && "lvalue-to-rvalue applied to r-value!");
+ return Visit(const_cast<Expr *>(subExpr));
case CK_IntegralCast: {
- assert(!cir::MissingFeatures::scalarConversionOpts());
- return emitScalarConversion(Visit(e), e->getType(), destTy,
+ ScalarConversionOpts opts;
+ if (auto *ice = dyn_cast<ImplicitCastExpr>(ce)) {
+ if (!ice->isPartOfExplicitCast())
+ opts = ScalarConversionOpts(cgf.sanOpts);
+ }
+ return emitScalarConversion(Visit(subExpr), subExpr->getType(), destTy,
+ ce->getExprLoc(), opts);
+ }
+
+ case CK_FloatingRealToComplex:
+ case CK_FloatingComplexCast:
+ case CK_IntegralRealToComplex:
+ case CK_IntegralComplexCast:
+ case CK_IntegralComplexToFloatingComplex:
+ case CK_FloatingComplexToIntegralComplex:
+ llvm_unreachable("scalar cast to non-scalar value");
+
+ case CK_PointerToIntegral: {
+ assert(!destTy->isBooleanType() && "bool should use PointerToBool");
+ if (cgf.cgm.getCodeGenOpts().StrictVTablePointers)
+ cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(),
+ "strict vtable pointers");
+ return builder.createPtrToInt(Visit(subExpr), cgf.convertType(destTy));
+ }
+ case CK_ToVoid:
+ cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(),
+ "ignored expression on void cast");
+ return nullptr;
+
+ case CK_IntegralToFloating:
+ case CK_FloatingToIntegral:
+ case CK_FloatingCast:
+ case CK_FixedPointToFloating:
+ case CK_FloatingToFixedPoint: {
+ if (kind == CK_FixedPointToFloating || kind == CK_FloatingToFixedPoint) {
+ cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(),
+ "fixed point casts");
+ return {};
----------------
mmha wrote:
Good to know you standardized on `{}`. I changed all instances of `return nullptr` to that.
https://github.com/llvm/llvm-project/pull/130690
More information about the cfe-commits
mailing list