Skip to content

Commit 1031f14

Browse files
authored
[CIR] Implement CK_LValueToRValueBitCast for ComplexType (#150296)
This change adds support for CK_LValueToRValueBitCast for ComplexType #141365
1 parent 96e5eed commit 1031f14

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,12 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
194194
}
195195

196196
case CK_LValueToRValueBitCast: {
197-
cgf.cgm.errorNYI("ComplexExprEmitter::emitCast CK_LValueToRValueBitCast");
198-
return {};
197+
LValue sourceLVal = cgf.emitLValue(op);
198+
Address addr = sourceLVal.getAddress().withElementType(
199+
builder, cgf.convertTypeForMem(destTy));
200+
LValue destLV = cgf.makeAddrLValue(addr, destTy);
201+
assert(!cir::MissingFeatures::opTBAA());
202+
return emitLoadOfLValue(destLV, op->getExprLoc());
199203
}
200204

201205
case CK_BitCast:

clang/test/CIR/CodeGen/complex-cast.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,33 @@ void complex_to_complex_cast() {
326326
// OGCG: store i32 %[[REAL_INT_CAST]], ptr {{.*}}, align 4
327327
// OGCG: store i32 %[[IMAG_INT_CAST]], ptr getelementptr inbounds nuw ({ i32, i32 }, ptr {{.*}}, i32 0, i32 1), align 4
328328

329+
struct CX {
330+
double real;
331+
double imag;
332+
};
333+
334+
void lvalue_to_rvalue_bitcast() {
335+
CX a;
336+
double _Complex b = __builtin_bit_cast(double _Complex, a);
337+
}
338+
339+
340+
// CIR-BEFORE: %{{.*}} = cir.cast(bitcast, %{{.*}} : !cir.ptr<!rec_CX>), !cir.ptr<!cir.complex<!cir.double>>
341+
342+
// CIR-AFTER: %{{.*}} = cir.cast(bitcast, %{{.*}} : !cir.ptr<!rec_CX>), !cir.ptr<!cir.complex<!cir.double>>
343+
344+
// LLVM: %[[PTR_ADDR:.*]] = alloca %struct.CX, i64 1, align 8
345+
// LLVM: %[[COMPLEX_ADDR:.*]] = alloca { double, double }, i64 1, align 8
346+
// LLVM: %[[PTR_TO_COMPLEX:.*]] = load { double, double }, ptr %[[PTR_ADDR]], align 8
347+
// LLVM: store { double, double } %[[PTR_TO_COMPLEX]], ptr %[[COMPLEX_ADDR]], align 8
348+
349+
// OGCG: %[[A_ADDR:.*]] = alloca %struct.CX, align 8
350+
// OGCG: %[[B_ADDR:.*]] = alloca { double, double }, align 8
351+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[A_ADDR]], i32 0, i32 0
352+
// OGCG: %[[A_REAL:.*]] = load double, ptr %[[A_REAL_PTR]], align 8
353+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[A_ADDR]], i32 0, i32 1
354+
// OGCG: %[[A_IMAG:.*]] = load double, ptr %[[A_IMAG_PTR]], align 8
355+
// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[B_ADDR]], i32 0, i32 0
356+
// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[B_ADDR]], i32 0, i32 1
357+
// OGCG: store double %[[A_REAL]], ptr %[[B_REAL_PTR]], align 8
358+
// OGCG: store double %[[A_IMAG]], ptr %[[B_IMAG_PTR]], align 8

0 commit comments

Comments
 (0)