diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 4e2b2cb0e178..a7d82534383b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -1056,7 +1056,8 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *E) { cir::GlobalOp var = CGM.getOrCreateStaticVarDecl( *VD, CGM.getCIRLinkageVarDefinition(VD, /*IsConstant=*/false)); auto getGlobalOp = builder.createGetGlobal(var); - auto actualElemTy = llvm::cast(getGlobalOp.getType()).getPointee(); + auto actualElemTy = + llvm::cast(getGlobalOp.getType()).getPointee(); addr = Address(getGlobalOp, actualElemTy, getContext().getDeclAlign(VD)); } else { llvm_unreachable("DeclRefExpr for decl not entered in LocalDeclMap?"); @@ -2017,7 +2018,15 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *E) { assert(0 && "NYI"); } case CK_LValueBitCast: { - assert(0 && "NYI"); + // This must be a reinterpret_cast (or c-style equivalent). + const auto *ce = cast(E); + + CGM.emitExplicitCastExprType(ce, this); + LValue LV = emitLValue(E->getSubExpr()); + Address V = LV.getAddress().withElementType( + builder, convertTypeForMem(ce->getTypeAsWritten()->getPointeeType())); + + return makeAddrLValue(V, E->getType(), LV.getBaseInfo(), LV.getTBAAInfo()); } case CK_AddressSpaceConversion: { LValue LV = emitLValue(E->getSubExpr()); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 87a6cf28965d..fecf449c86b1 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -428,8 +428,13 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind CK, Expr *Op, case CK_UserDefinedConversion: llvm_unreachable("NYI"); - case CK_LValueBitCast: - llvm_unreachable("NYI"); + case CK_LValueBitCast: { + LValue origLV = CGF.emitLValue(Op); + Address addr = + origLV.getAddress().withElementType(Builder, CGF.convertType(DestTy)); + LValue destLV = CGF.makeAddrLValue(addr, DestTy); + return emitLoadOfLValue(destLV, Op->getExprLoc()); + } case CK_LValueToRValueBitCast: { LValue SourceLVal = CGF.emitLValue(Op); diff --git a/clang/test/CIR/CodeGen/complex-cast.cpp b/clang/test/CIR/CodeGen/complex-cast.cpp new file mode 100644 index 000000000000..c40440096590 --- /dev/null +++ b/clang/test/CIR/CodeGen/complex-cast.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -x c++ -fclangir -emit-cir -mmlir --mlir-print-ir-before=cir-canonicalize -o %t.cir %s 2>&1 | FileCheck --check-prefix=CIR-BEFORE %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -x c++ -fclangir -emit-cir -mmlir --mlir-print-ir-after=cir-canonicalize -o %t.cir %s 2>&1 | FileCheck --check-prefix=CIR-AFTER %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -o %t.ll %s +// RUN: FileCheck --input-file=%t.ll --check-prefixes=LLVM %s + +struct CX { + double real; + double imag; +}; + +void complex_lvalue_bitcast() { + struct CX a; + (double _Complex &)a = {}; +} + +// CIR-BEFORE: %{{.*}} = cir.cast(bitcast, %{{.*}} : !cir.ptr), !cir.ptr> + +// CIR-AFTER: %{{.*}} = cir.cast(bitcast, %{{.*}} : !cir.ptr), !cir.ptr> + +// LLVM: %[[A_ADDR:.*]] = alloca %struct.CX, i64 1, align 8 +// LLVM: store { double, double } zeroinitializer, ptr %[[A_ADDR]], align 8