From 14f0d8d616c42e07d68bf855722c004b0b4125eb Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sun, 5 Oct 2025 20:40:17 +0200 Subject: [PATCH] [CIR] Backport CXX new for ComplexType with init --- clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 5 +++-- clang/test/CIR/CodeGen/new.cpp | 28 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp index b597d751da9e..1f4449cb5a39 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp @@ -302,7 +302,7 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr( "Destructor shouldn't have explicit parameters"); assert(ReturnValue.isNull() && "Destructor shouldn't have return value"); if (useVirtualCall) { - CIRGenFunction* CGF = CGM.getCurrCIRGenFun(); + CIRGenFunction *CGF = CGM.getCurrCIRGenFun(); CGM.getCXXABI().emitVirtualDestructorCall( *CGF, dtor, Dtor_Complete, This.getAddress(), dyn_cast(CE)); @@ -961,7 +961,8 @@ static void StoreAnyExprIntoOneUnit(CIRGenFunction &CGF, const Expr *Init, CGF.makeAddrLValue(NewPtr, AllocType), false); return; case cir::TEK_Complex: - llvm_unreachable("NYI"); + CGF.emitComplexExprIntoLValue(Init, CGF.makeAddrLValue(NewPtr, AllocType), + /*isInit*/ true); return; case cir::TEK_Aggregate: { AggValueSlot Slot = AggValueSlot::forAddr( diff --git a/clang/test/CIR/CodeGen/new.cpp b/clang/test/CIR/CodeGen/new.cpp index 2d400e4326b3..6fa1809b5f7e 100644 --- a/clang/test/CIR/CodeGen/new.cpp +++ b/clang/test/CIR/CodeGen/new.cpp @@ -329,3 +329,31 @@ void t_multidim_init() { // CHECK: %[[ELEM_12_PTR:.*]] = cir.get_element %[[ARRAY_ELEM1_PTR]][%[[OFFSET6]]] : (!cir.ptr>, !s64i) -> !cir.ptr // CHECK: %[[ELEM_12_VAL:.*]] = cir.const #cir.int<6> : !s32i // CHECK: cir.store{{.*}} %[[ELEM_12_VAL]], %[[ELEM_12_PTR]] : !s32i, !cir.ptr + +void test_new_with_complex_type() { + _Complex float *a = new _Complex float{1.0f, 2.0f}; +} + +// CHECK: cir.func{{.*}} @_Z26test_new_with_complex_typev +// CHECK: %[[A_ADDR:.*]] = cir.alloca !cir.ptr>, !cir.ptr>>, ["a", init] +// CHECK: %[[COMPLEX_SIZE:.*]] = cir.const #cir.int<8> : !u64i +// CHECK: %[[NEW_COMPLEX:.*]] = cir.call @_Znwm(%[[COMPLEX_SIZE]]) : (!u64i) -> !cir.ptr +// CHECK: %[[COMPLEX_PTR:.*]] = cir.cast bitcast %[[NEW_COMPLEX]] : !cir.ptr -> !cir.ptr> +// CHECK: %[[COMPLEX_VAL:.*]] = cir.const #cir.complex<#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> : !cir.float> : !cir.complex +// CHECK: cir.store{{.*}} %[[COMPLEX_VAL]], %[[COMPLEX_PTR]] : !cir.complex, !cir.ptr> +// CHECK: cir.store{{.*}} %[[COMPLEX_PTR]], %[[A_ADDR]] : !cir.ptr>, !cir.ptr>> + +// LLVM: define{{.*}} void @_Z26test_new_with_complex_typev +// LLVM: %[[A_ADDR:.*]] = alloca ptr, i64 1, align 8 +// LLVM: %[[NEW_COMPLEX:.*]] = call ptr @_Znwm(i64 8) +// LLVM: store { float, float } { float 1.000000e+00, float 2.000000e+00 }, ptr %[[NEW_COMPLEX]], align 8 +// LLVM: store ptr %[[NEW_COMPLEX]], ptr %[[A_ADDR]], align 8 + +// OGCG: define{{.*}} void @_Z26test_new_with_complex_typev +// OGCG: %[[A_ADDR:.*]] = alloca ptr, align 8 +// OGCG: %[[NEW_COMPLEX:.*]] = call noalias noundef nonnull ptr @_Znwm(i64 noundef 8) +// OGCG: %[[COMPLEX_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[NEW_COMPLEX]], i32 0, i32 0 +// OGCG: %[[COMPLEX_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[NEW_COMPLEX]], i32 0, i32 1 +// OGCG: store float 1.000000e+00, ptr %[[COMPLEX_REAL_PTR]], align 8 +// OGCG: store float 2.000000e+00, ptr %[[COMPLEX_IMAG_PTR]], align 4 +// OGCG: store ptr %[[NEW_COMPLEX]], ptr %[[A_ADDR]], align 8