diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 5e8f2d9b55d1..f55a3a08ca25 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -431,8 +431,14 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind CK, Expr *Op, case CK_LValueBitCast: llvm_unreachable("NYI"); - case CK_LValueToRValueBitCast: - llvm_unreachable("NYI"); + case CK_LValueToRValueBitCast: { + LValue SourceLVal = CGF.emitLValue(Op); + Address Addr = SourceLVal.getAddress().withElementType( + Builder, CGF.convertTypeForMem(DestTy)); + LValue DestLV = CGF.makeAddrLValue(Addr, DestTy); + DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo()); + return emitLoadOfLValue(DestLV, Op->getExprLoc()); + } case CK_BitCast: case CK_BaseToDerived: diff --git a/clang/test/CIR/CodeGen/complex-cast.c b/clang/test/CIR/CodeGen/complex-cast.c index 41253fdddd0f..521262569444 100644 --- a/clang/test/CIR/CodeGen/complex-cast.c +++ b/clang/test/CIR/CodeGen/complex-cast.c @@ -199,6 +199,29 @@ void complex_to_bool() { // CHECK: } +struct CX { + double real; + double imag; +}; + +void lvalue_to_rvalue_bitcast() { + struct CX a; + double _Complex b = __builtin_bit_cast(double _Complex, a); +} + +// CHECK-LABEL: @lvalue_to_rvalue_bitcast() + +// CIR-BEFORE: %{{.+}} = cir.cast(bitcast, %{{.+}} : !cir.ptr), !cir.ptr> + +// CIR-AFTER: %{{.+}} = cir.cast(bitcast, %{{.+}} : !cir.ptr), !cir.ptr> + +// LLVM: %[[PTR_ADDR:.*]] = alloca %struct.CX, i64 1, align 8 +// LLVM: %[[COMPLEX_ADDR:.*]] = alloca { double, double }, i64 1, align 8 +// LLVM: %[[PTR_TO_COMPLEX:.*]] = load { double, double }, ptr %[[PTR_ADDR]], align 8 +// LLVM: store { double, double } %[[PTR_TO_COMPLEX]], ptr %[[COMPLEX_ADDR]], align 8 + +// CHECK: } + void complex_to_complex_cast() { cd = cf; ci = cs;