https://github.com/HendrikHuebner updated https://github.com/llvm/llvm-project/pull/168281
From 7b2d881dd8a510efd08c6218b14ce66cb62c27c0 Mon Sep 17 00:00:00 2001 From: hhuebner <[email protected]> Date: Wed, 12 Nov 2025 21:20:30 +0100 Subject: [PATCH 1/8] [CIR] Replace trivial copy constructors with cir.copy --- .../Dialect/Transforms/LoweringPrepare.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index f8f354c2d1072..24a164cb5af6d 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -74,6 +74,7 @@ struct LoweringPreparePass void lowerDynamicCastOp(cir::DynamicCastOp op); void lowerArrayDtor(cir::ArrayDtor op); void lowerArrayCtor(cir::ArrayCtor op); + void lowerTrivialConstructorCall(cir::CallOp op); /// Build the function that initializes the specified global cir::FuncOp buildCXXGlobalVarDeclInitFunc(cir::GlobalOp op); @@ -1085,6 +1086,29 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor op) { true); } +void LoweringPreparePass::lowerTrivialConstructorCall(cir::CallOp op) { + FuncOp funcOp = getCalledFunction(op); + if (!funcOp) + return; + + mlir::Attribute cxxSpecialMember = funcOp.getCxxSpecialMemberAttr(); + if (!cxxSpecialMember) + return; + + if (auto cxxCtor = dyn_cast<cir::CXXCtorAttr>(cxxSpecialMember)) { + if (cxxCtor.getCtorKind() == cir::CtorKind::Copy) { + // Replace the trivial copy constructor call with a `CopyOp` + CIRBaseBuilderTy builder(getContext()); + auto operands = op.getOperands(); + mlir::Value dest = operands[0]; + mlir::Value src = operands[1]; + builder.setInsertionPoint(op); + builder.createCopy(dest, src); + op.erase(); + } + } +} + void LoweringPreparePass::runOnOp(mlir::Operation *op) { if (auto arrayCtor = dyn_cast<cir::ArrayCtor>(op)) { lowerArrayCtor(arrayCtor); @@ -1107,6 +1131,8 @@ void LoweringPreparePass::runOnOp(mlir::Operation *op) { globalCtorList.emplace_back(fnOp.getName(), globalCtor.value()); else if (auto globalDtor = fnOp.getGlobalDtorPriority()) globalDtorList.emplace_back(fnOp.getName(), globalDtor.value()); + } else if (auto callOp = dyn_cast<cir::CallOp>(op)) { + lowerTrivialConstructorCall(callOp); } } From 4532ea4ef934307d1ddb8c40d7959ddb02a5292c Mon Sep 17 00:00:00 2001 From: hhuebner <[email protected]> Date: Sun, 16 Nov 2025 13:47:45 +0100 Subject: [PATCH 2/8] Add cir parsing test --- .../Dialect/Transforms/LoweringPrepare.cpp | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index 24a164cb5af6d..f8f354c2d1072 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -74,7 +74,6 @@ struct LoweringPreparePass void lowerDynamicCastOp(cir::DynamicCastOp op); void lowerArrayDtor(cir::ArrayDtor op); void lowerArrayCtor(cir::ArrayCtor op); - void lowerTrivialConstructorCall(cir::CallOp op); /// Build the function that initializes the specified global cir::FuncOp buildCXXGlobalVarDeclInitFunc(cir::GlobalOp op); @@ -1086,29 +1085,6 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor op) { true); } -void LoweringPreparePass::lowerTrivialConstructorCall(cir::CallOp op) { - FuncOp funcOp = getCalledFunction(op); - if (!funcOp) - return; - - mlir::Attribute cxxSpecialMember = funcOp.getCxxSpecialMemberAttr(); - if (!cxxSpecialMember) - return; - - if (auto cxxCtor = dyn_cast<cir::CXXCtorAttr>(cxxSpecialMember)) { - if (cxxCtor.getCtorKind() == cir::CtorKind::Copy) { - // Replace the trivial copy constructor call with a `CopyOp` - CIRBaseBuilderTy builder(getContext()); - auto operands = op.getOperands(); - mlir::Value dest = operands[0]; - mlir::Value src = operands[1]; - builder.setInsertionPoint(op); - builder.createCopy(dest, src); - op.erase(); - } - } -} - void LoweringPreparePass::runOnOp(mlir::Operation *op) { if (auto arrayCtor = dyn_cast<cir::ArrayCtor>(op)) { lowerArrayCtor(arrayCtor); @@ -1131,8 +1107,6 @@ void LoweringPreparePass::runOnOp(mlir::Operation *op) { globalCtorList.emplace_back(fnOp.getName(), globalCtor.value()); else if (auto globalDtor = fnOp.getGlobalDtorPriority()) globalDtorList.emplace_back(fnOp.getName(), globalDtor.value()); - } else if (auto callOp = dyn_cast<cir::CallOp>(op)) { - lowerTrivialConstructorCall(callOp); } } From b46cf9634f9f9ae2e44ea83048f40f263ff822ea Mon Sep 17 00:00:00 2001 From: hhuebner <[email protected]> Date: Sun, 16 Nov 2025 14:06:35 +0100 Subject: [PATCH 3/8] Lower trivial copy constructor to cir::CopyOp --- .../Dialect/Transforms/LoweringPrepare.cpp | 25 ++++++++++++++++++- .../CIR/CodeGen/cxx-special-member-attr.cpp | 9 ++++--- clang/test/CIR/CodeGen/struct.cpp | 2 +- .../combined-firstprivate-clause.cpp | 4 +-- .../compute-firstprivate-clause-templates.cpp | 2 +- .../compute-firstprivate-clause.cpp | 6 ++--- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index f8f354c2d1072..a465e6ba04945 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -74,6 +74,7 @@ struct LoweringPreparePass void lowerDynamicCastOp(cir::DynamicCastOp op); void lowerArrayDtor(cir::ArrayDtor op); void lowerArrayCtor(cir::ArrayCtor op); + void lowerTrivialCopyCall(cir::CallOp op); /// Build the function that initializes the specified global cir::FuncOp buildCXXGlobalVarDeclInitFunc(cir::GlobalOp op); @@ -1085,6 +1086,26 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor op) { true); } +void LoweringPreparePass::lowerTrivialCopyCall(cir::CallOp op) { + FuncOp funcOp = getCalledFunction(op); + if (!funcOp) + return; + + std::optional<cir::CtorKind> ctorKind = funcOp.getCxxConstructorKind(); + if (ctorKind && *ctorKind == cir::CtorKind::Copy && + funcOp.isCxxTrivialMemberFunction()) { + llvm::outs() << "success \n"; + // Replace the trivial copy constructor call with a `CopyOp` + CIRBaseBuilderTy builder(getContext()); + auto operands = op.getOperands(); + mlir::Value dest = operands[0]; + mlir::Value src = operands[1]; + builder.setInsertionPoint(op); + builder.createCopy(dest, src); + op.erase(); + } +} + void LoweringPreparePass::runOnOp(mlir::Operation *op) { if (auto arrayCtor = dyn_cast<cir::ArrayCtor>(op)) { lowerArrayCtor(arrayCtor); @@ -1102,6 +1123,8 @@ void LoweringPreparePass::runOnOp(mlir::Operation *op) { lowerDynamicCastOp(dynamicCast); } else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op)) { lowerUnaryOp(unary); + } else if (auto callOp = dyn_cast<cir::CallOp>(op)) { + lowerTrivialCopyCall(callOp); } else if (auto fnOp = dyn_cast<cir::FuncOp>(op)) { if (auto globalCtor = fnOp.getGlobalCtorPriority()) globalCtorList.emplace_back(fnOp.getName(), globalCtor.value()); @@ -1120,7 +1143,7 @@ void LoweringPreparePass::runOnOperation() { op->walk([&](mlir::Operation *op) { if (mlir::isa<cir::ArrayCtor, cir::ArrayDtor, cir::CastOp, cir::ComplexMulOp, cir::ComplexDivOp, cir::DynamicCastOp, - cir::FuncOp, cir::GlobalOp, cir::UnaryOp>(op)) + cir::FuncOp, cir::CallOp, cir::GlobalOp, cir::UnaryOp>(op)) opsToTransform.push_back(op); }); diff --git a/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp b/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp index 815ef2c2aaa25..cd1377ac04eac 100644 --- a/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp +++ b/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp @@ -3,8 +3,9 @@ struct Flub { int a = 123; - // CIR: @_ZN4FlubC1ERKS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Flub, copy, trivial true>> - // CIR: @_ZN4FlubC2EOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Flub, move, trivial true> + // COM: Trivial copy constructors/assignments are replaced with cir.copy + // CIR: cir.copy {{.*}} : !cir.ptr<!rec_Flub> + // CIR: @_ZN4FlubC1EOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Flub, move, trivial true> // CIR: @_ZN4FlubaSERKS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) -> !cir.ptr<!rec_Flub> special_member<#cir.cxx_assign<!rec_Flub, copy, trivial true>> // CIR: @_ZN4FlubaSEOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) -> !cir.ptr<!rec_Flub> special_member<#cir.cxx_assign<!rec_Flub, move, trivial true>> }; @@ -42,7 +43,7 @@ struct Foo { ~Foo(); }; -void trivial() { +void trivial_func() { Flub f1{}; Flub f2 = f1; Flub f3 = static_cast<Flub&&>(f1); @@ -50,7 +51,7 @@ void trivial() { f1 = static_cast<Flub&&>(f3); } -void non_trivial() { +void non_trivial_func() { Foo f1{}; Foo f2 = f1; Foo f3 = static_cast<Foo&&>(f1); diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp index c15e7e7c57b9f..969ab46339d62 100644 --- a/clang/test/CIR/CodeGen/struct.cpp +++ b/clang/test/CIR/CodeGen/struct.cpp @@ -109,7 +109,7 @@ void paren_expr() { // CIR: %[[B_ADDR:.*]] = cir.alloca !rec_Point, !cir.ptr<!rec_Point>, ["b", init] // CIR: %[[CONST:.*]] = cir.const #cir.zero : !rec_Point // CIR: cir.store{{.*}} %[[CONST]], %[[A_ADDR]] : !rec_Point, !cir.ptr<!rec_Point> -// CIR: cir.call @_ZZ10paren_exprvEN5PointC1ERKS_(%[[B_ADDR]], %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_Point>, !cir.ptr<!rec_Point>) -> () +// CIR: cir.copy %[[A_ADDR]] to %[[B_ADDR]]) -> !cir.ptr<!rec_Point> // LLVM: define{{.*}} void @_Z10paren_exprv() // LLVM: %[[A_ADDR:.*]] = alloca %struct.Point, i64 1, align 4 diff --git a/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp b/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp index 94f3f1ace4350..3cd8209d05076 100644 --- a/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp +++ b/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp @@ -43,7 +43,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NoCopyConstruct> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NoCopyConstruct> {{.*}}): -// CHECK-NEXT: cir.call @_ZN15NoCopyConstructC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_NoCopyConstruct>, !cir.ptr<!rec_NoCopyConstruct>) -> () +// CHECK-NEXT: cir.copy %[[ARG_FROM]] TO %[[ARG_FROM]] -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // @@ -176,7 +176,7 @@ struct HasDtor { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct> -// CHECK-NEXT: cir.call @_ZN15NoCopyConstructC1ERKS_(%[[STRIDE_TO]], %[[STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_NoCopyConstruct>, !cir.ptr<!rec_NoCopyConstruct>) -> () +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i diff --git a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp index ed968e21630cc..fb424f65f28cd 100644 --- a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp +++ b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp @@ -30,7 +30,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}): -// CHECK-NEXT: cir.call @_ZN14NonDefaultCtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_NonDefaultCtor>, !cir.ptr<!rec_NonDefaultCtor>) -> () +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]]) -> !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // diff --git a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp index a2c6c3834b1e2..ecc7a49cf8c62 100644 --- a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp +++ b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp @@ -43,7 +43,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NoCopyConstruct> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NoCopyConstruct> {{.*}}): -// CHECK-NEXT: cir.call @_ZN15NoCopyConstructC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_NoCopyConstruct>, !cir.ptr<!rec_NoCopyConstruct>) -> () +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // @@ -63,7 +63,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}): -// CHECK-NEXT: cir.call @_ZN14NonDefaultCtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_NonDefaultCtor>, !cir.ptr<!rec_NonDefaultCtor>) -> () +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]]) -> cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // @@ -176,7 +176,7 @@ struct HasDtor { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct> -// CHECK-NEXT: cir.call @_ZN15NoCopyConstructC1ERKS_(%[[STRIDE_TO]], %[[STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_NoCopyConstruct>, !cir.ptr<!rec_NoCopyConstruct>) -> () +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]]) -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i From ab00cf9fe79442af288739ffe043fcd4d2e49b1b Mon Sep 17 00:00:00 2001 From: hhuebner <[email protected]> Date: Sun, 23 Nov 2025 15:22:37 +0100 Subject: [PATCH 4/8] Fix tests --- clang/test/CIR/CodeGen/lambda.cpp | 4 ++-- clang/test/CIR/CodeGen/struct.cpp | 18 ++++++++---------- .../combined-firstprivate-clause.cpp | 12 ++++++------ .../compute-firstprivate-clause-templates.cpp | 4 ++-- .../compute-firstprivate-clause.cpp | 13 +++++++------ .../firstprivate-clause-recipes.cpp | 6 +++--- 6 files changed, 28 insertions(+), 29 deletions(-) diff --git a/clang/test/CIR/CodeGen/lambda.cpp b/clang/test/CIR/CodeGen/lambda.cpp index 91380b9bea296..b766d7ba5daf6 100644 --- a/clang/test/CIR/CodeGen/lambda.cpp +++ b/clang/test/CIR/CodeGen/lambda.cpp @@ -334,7 +334,7 @@ struct A { // CIR: cir.scope { // CIR: %[[LAM_ADDR:.*]] = cir.alloca ![[REC_LAM_A]], !cir.ptr<![[REC_LAM_A]]>, ["ref.tmp0"] // CIR: %[[STRUCT_A:.*]] = cir.get_member %[[LAM_ADDR]][0] {name = "this"} : !cir.ptr<![[REC_LAM_A]]> -> !cir.ptr<!rec_A> -// CIR: cir.call @_ZN1AC1ERKS_(%[[STRUCT_A]], %[[THIS]]){{.*}} : (!cir.ptr<!rec_A>, !cir.ptr<!rec_A>){{.*}} -> () +// CIR: cir.copy %[[THIS]] to %[[STRUCT_A]] : !cir.ptr<!rec_A> // CIR: %[[LAM_RET:.*]] = cir.call @_ZZN1A3fooEvENKUlvE_clEv(%[[LAM_ADDR]]) // CIR: cir.store{{.*}} %[[LAM_RET]], %[[RETVAL]] // CIR: } @@ -350,7 +350,7 @@ struct A { // LLVM: br label %[[SCOPE_BB:.*]] // LLVM: [[SCOPE_BB]]: // LLVM: %[[STRUCT_A:.*]] = getelementptr %[[REC_LAM_A]], ptr %[[LAM_ALLOCA]], i32 0, i32 0 -// LLVM: call void @_ZN1AC1ERKS_(ptr %[[STRUCT_A]], ptr %[[THIS]]) +// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[STRUCT_A]], ptr %[[THIS]], i32 4, i1 false) // LLVM: %[[LAM_RET:.*]] = call i32 @_ZZN1A3fooEvENKUlvE_clEv(ptr %[[LAM_ALLOCA]]) // LLVM: store i32 %[[LAM_RET]], ptr %[[RETVAL]] // LLVM: br label %[[RET_BB:.*]] diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp index 969ab46339d62..dc3e24113d8d8 100644 --- a/clang/test/CIR/CodeGen/struct.cpp +++ b/clang/test/CIR/CodeGen/struct.cpp @@ -109,13 +109,13 @@ void paren_expr() { // CIR: %[[B_ADDR:.*]] = cir.alloca !rec_Point, !cir.ptr<!rec_Point>, ["b", init] // CIR: %[[CONST:.*]] = cir.const #cir.zero : !rec_Point // CIR: cir.store{{.*}} %[[CONST]], %[[A_ADDR]] : !rec_Point, !cir.ptr<!rec_Point> -// CIR: cir.copy %[[A_ADDR]] to %[[B_ADDR]]) -> !cir.ptr<!rec_Point> +// CIR: cir.copy %[[A_ADDR]] to %[[B_ADDR]] : !cir.ptr<!rec_Point> // LLVM: define{{.*}} void @_Z10paren_exprv() // LLVM: %[[A_ADDR:.*]] = alloca %struct.Point, i64 1, align 4 // LLVM: %[[B_ADDR:.*]] = alloca %struct.Point, i64 1, align 4 // LLVM: store %struct.Point zeroinitializer, ptr %[[A_ADDR]], align 4 -// LLVM: call void @_ZZ10paren_exprvEN5PointC1ERKS_(ptr %[[B_ADDR]], ptr %[[A_ADDR]]) +// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[B_ADDR]], ptr %[[A_ADDR]], i32 8, i1 false) // OGCG: define{{.*}} void @_Z10paren_exprv() // OGCG: %[[A_ADDR:.*]] = alloca %struct.Point, align 4 @@ -133,14 +133,13 @@ void choose_expr() { // CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a"] // CIR: %[[B_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["b"] // CIR: %[[C_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["c", init] -// TODO(cir): Call to default copy constructor should be replaced by `cir.copy` op -// CIR: cir.call @_ZN9CompleteSC1ERKS_(%[[C_ADDR]], %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> () +// CIR: cir.copy %[[A_ADDR]] to %[[C_ADDR]] : !cir.ptr<!rec_CompleteS> // LLVM: define{{.*}} void @_Z11choose_exprv() // LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4 // LLVM: %[[B_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4 // LLVM: %[[C_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4 -// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %[[C_ADDR]], ptr %[[A_ADDR]]) +// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[C_ADDR]], ptr %[[A_ADDR]], i32 8, i1 false) // OGCG: define{{.*}} void @_Z11choose_exprv() // OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4 @@ -160,15 +159,14 @@ void generic_selection() { // CIR: %[[B_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["b"] // CIR: %[[C_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["c"] // CIR: %[[D_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["d", init] -// TODO(cir): Call to default copy constructor should be replaced by `cir.copy` op -// CIR: cir.call @_ZN9CompleteSC1ERKS_(%[[D_ADDR]], %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> () +// CIR: cir.copy %[[A_ADDR]] to %[[D_ADDR]] : !cir.ptr<!rec_CompleteS> // LLVM: define{{.*}} void @_Z17generic_selectionv() // LLVM: %1 = alloca %struct.CompleteS, i64 1, align 4 // LLVM: %2 = alloca %struct.CompleteS, i64 1, align 4 // LLVM: %3 = alloca i32, i64 1, align 4 // LLVM: %4 = alloca %struct.CompleteS, i64 1, align 4 -// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %4, ptr %1) +// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %4, ptr %1, i32 8, i1 false) // OGCG: define{{.*}} void @_Z17generic_selectionv() // OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4 @@ -188,7 +186,7 @@ void designated_init_update_expr() { // CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a"] // CIR: %[[B_ADDR:.*]] = cir.alloca !rec_Container, !cir.ptr<!rec_Container>, ["b", init] // CIR: %[[C_ADDR:.*]] = cir.get_member %[[B_ADDR]][0] {name = "c"} : !cir.ptr<!rec_Container> -> !cir.ptr<!rec_CompleteS> -// CIR: cir.call @_ZN9CompleteSC1ERKS_(%2, %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> () +// CIR: cir.copy %[[A_ADDR]] to %[[C_ADDR]] : !cir.ptr<!rec_CompleteS> // CIR: %[[ELEM_0_PTR:.*]] = cir.get_member %[[C_ADDR]][0] {name = "a"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s32i> // CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i // CIR: cir.store{{.*}} %[[CONST_1]], %[[ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i> @@ -197,7 +195,7 @@ void designated_init_update_expr() { // LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4 // LLVM: %[[B_ADDR:.*]] = alloca %struct.Container, i64 1, align 4 // LLVM: %[[C_ADDR:.*]] = getelementptr %struct.Container, ptr %[[B_ADDR]], i32 0, i32 0 -// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %[[C_ADDR]], ptr %[[A_ADDR]]) +// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[C_ADDR]], ptr %[[A_ADDR]], i32 8, i1 false) // LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 0 // LLVM: store i32 1, ptr %[[ELEM_0_PTR]], align 4 // LLVM: %[[ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 1 diff --git a/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp b/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp index 3cd8209d05076..b1fba89739109 100644 --- a/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp +++ b/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp @@ -43,7 +43,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NoCopyConstruct> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NoCopyConstruct> {{.*}}): -// CHECK-NEXT: cir.copy %[[ARG_FROM]] TO %[[ARG_FROM]] -> !cir.ptr<!rec_NoCopyConstruct> +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // @@ -63,7 +63,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}): -// CHECK-NEXT: cir.call @_ZN14NonDefaultCtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_NonDefaultCtor>, !cir.ptr<!rec_NonDefaultCtor>) -> () +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // @@ -73,7 +73,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}): -// CHECK-NEXT: cir.call @_ZN7HasDtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_HasDtor>, !cir.ptr<!rec_HasDtor>) -> () +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_HasDtor> // CHECK-NEXT: acc.yield // CHECK-NEXT: } destroy { // CHECK-NEXT: ^bb0(%[[ORIG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}): @@ -176,7 +176,7 @@ struct HasDtor { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct> -// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] -> !cir.ptr<!rec_NoCopyConstruct> +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i @@ -246,7 +246,7 @@ struct HasDtor { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NonDefaultCtor>, !u64i) -> !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>> -> !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NonDefaultCtor>, !u64i) -> !cir.ptr<!rec_NonDefaultCtor> -// CHECK-NEXT: cir.call @_ZN14NonDefaultCtorC1ERKS_(%[[STRIDE_TO]], %[[STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_NonDefaultCtor>, !cir.ptr<!rec_NonDefaultCtor>) -> () +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i @@ -281,7 +281,7 @@ struct HasDtor { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_HasDtor>, !u64i) -> !cir.ptr<!rec_HasDtor> // CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_HasDtor x 5>> -> !cir.ptr<!rec_HasDtor> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_HasDtor>, !u64i) -> !cir.ptr<!rec_HasDtor> -// CHECK-NEXT: cir.call @_ZN7HasDtorC1ERKS_(%[[STRIDE_TO]], %[[STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_HasDtor>, !cir.ptr<!rec_HasDtor>) -> () +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_HasDtor> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i diff --git a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp index fb424f65f28cd..30f1cc4d68123 100644 --- a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp +++ b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp @@ -30,7 +30,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}): -// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]]) -> !cir.ptr<!rec_NonDefaultCtor> +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // @@ -40,7 +40,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}): -// CHECK-NEXT: cir.call @_ZN7HasDtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_HasDtor>, !cir.ptr<!rec_HasDtor>) -> () +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_HasDtor> // CHECK-NEXT: acc.yield // CHECK-NEXT: } destroy { // CHECK-NEXT: ^bb0(%[[ORIG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}): diff --git a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp index ecc7a49cf8c62..aa69c08055da1 100644 --- a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp +++ b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fopenacc -triple x86_64-linux-gnu -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir -triple x86_64-linux-pc %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenacc -triple x86_64-linux-gnu -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir -triple x86_64-linux-pc %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s struct NoCopyConstruct {}; @@ -63,7 +64,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}): -// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]]) -> cir.ptr<!rec_NonDefaultCtor> +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // @@ -73,7 +74,7 @@ struct HasDtor { // CHECK-NEXT: acc.yield // CHECK-NEXT: } copy { // CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}): -// CHECK-NEXT: cir.call @_ZN7HasDtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_HasDtor>, !cir.ptr<!rec_HasDtor>) -> () +// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_HasDtor> // CHECK-NEXT: acc.yield // CHECK-NEXT: } destroy { // CHECK-NEXT: ^bb0(%[[ORIG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}): @@ -176,7 +177,7 @@ struct HasDtor { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> -> !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct> -// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]]) -> !cir.ptr<!rec_NoCopyConstruct> +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i @@ -246,7 +247,7 @@ struct HasDtor { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NonDefaultCtor>, !u64i) -> !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>> -> !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NonDefaultCtor>, !u64i) -> !cir.ptr<!rec_NonDefaultCtor> -// CHECK-NEXT: cir.call @_ZN14NonDefaultCtorC1ERKS_(%[[STRIDE_TO]], %[[STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_NonDefaultCtor>, !cir.ptr<!rec_NonDefaultCtor>) -> () +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_NonDefaultCtor> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i @@ -281,7 +282,7 @@ struct HasDtor { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_HasDtor>, !u64i) -> !cir.ptr<!rec_HasDtor> // CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_HasDtor x 5>> -> !cir.ptr<!rec_HasDtor> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_HasDtor>, !u64i) -> !cir.ptr<!rec_HasDtor> -// CHECK-NEXT: cir.call @_ZN7HasDtorC1ERKS_(%[[STRIDE_TO]], %[[STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_HasDtor>, !cir.ptr<!rec_HasDtor>) -> () +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_HasDtor> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i diff --git a/clang/test/CIR/CodeGenOpenACC/firstprivate-clause-recipes.cpp b/clang/test/CIR/CodeGenOpenACC/firstprivate-clause-recipes.cpp index 95168812316ea..3a13a81b48828 100644 --- a/clang/test/CIR/CodeGenOpenACC/firstprivate-clause-recipes.cpp +++ b/clang/test/CIR/CodeGenOpenACC/firstprivate-clause-recipes.cpp @@ -75,7 +75,7 @@ void do_things(unsigned A, unsigned B) { // CHECK-NEXT: %[[BOUND1_STRIDE_FROM:.*]] = cir.ptr_stride %[[BOUND2_STRIDE_DECAY_FROM]], %[[ITR1_LOAD]] : (!cir.ptr<!rec_NoOps>, !u64i) -> !cir.ptr<!rec_NoOps> // CHECK-NEXT: %[[BOUND2_STRIDE_DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[BOUND2_STRIDE_TO]] : !cir.ptr<!cir.array<!rec_NoOps x 5>> -> !cir.ptr<!rec_NoOps> // CHECK-NEXT: %[[BOUND1_STRIDE_TO:.*]] = cir.ptr_stride %[[BOUND2_STRIDE_DECAY_TO]], %[[ITR1_LOAD]] : (!cir.ptr<!rec_NoOps>, !u64i) -> !cir.ptr<!rec_NoOps> -// CHECK-NEXT: cir.call @_ZN5NoOpsC1ERKS_(%[[BOUND1_STRIDE_TO]], %[[BOUND1_STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_NoOps>, !cir.ptr<!rec_NoOps>) -> () +// CHECK-NEXT: cir.copy %[[BOUND1_STRIDE_FROM]] to %[[BOUND1_STRIDE_TO]] : !cir.ptr<!rec_NoOps> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR1_LOAD]] = cir.load %[[ITR1]] : !cir.ptr<!u64i>, !u64i @@ -342,7 +342,7 @@ void do_things(unsigned A, unsigned B) { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[BOUND2_STRIDE_LOAD_FROM]], %[[ITR1_LOAD]] : (!cir.ptr<!rec_NoOps>, !u64i) -> !cir.ptr<!rec_NoOps> // CHECK-NEXT: %[[BOUND2_STRIDE_LOAD_TO:.*]] = cir.load %[[BOUND2_STRIDE_TO]] : !cir.ptr<!cir.ptr<!rec_NoOps>>, !cir.ptr<!rec_NoOps> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[BOUND2_STRIDE_LOAD_TO]], %[[ITR1_LOAD]] : (!cir.ptr<!rec_NoOps>, !u64i) -> !cir.ptr<!rec_NoOps> -// CHECK-NEXT: cir.call @_ZN5NoOpsC1ERKS_(%[[BOUND1_STRIDE_TO]], %[[BOUND1_STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_NoOps>, !cir.ptr<!rec_NoOps>) -> () +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_NoOps> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR1_LOAD]] = cir.load %[[ITR1]] : !cir.ptr<!u64i>, !u64i @@ -580,7 +580,7 @@ void do_things(unsigned A, unsigned B) { // CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[BOUND2_STRIDE_LOAD_FROM]], %[[ITR1_LOAD]] : (!cir.ptr<!rec_CtorDtor>, !u64i) -> !cir.ptr<!rec_CtorDtor> // CHECK-NEXT: %[[BOUND2_STRIDE_LOAD_TO:.*]] = cir.load %[[BOUND2_STRIDE_TO]] : !cir.ptr<!cir.ptr<!rec_CtorDtor>>, !cir.ptr<!rec_CtorDtor> // CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[BOUND2_STRIDE_LOAD_TO]], %[[ITR1_LOAD]] : (!cir.ptr<!rec_CtorDtor>, !u64i) -> !cir.ptr<!rec_CtorDtor> -// CHECK-NEXT: cir.call @_ZN8CtorDtorC1ERKS_(%[[BOUND1_STRIDE_TO]], %[[BOUND1_STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_CtorDtor>, !cir.ptr<!rec_CtorDtor>) -> () +// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_CtorDtor> // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR1_LOAD]] = cir.load %[[ITR1]] : !cir.ptr<!u64i>, !u64i From 448adb521aae15d6f0b02d983c7158823f538c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hendrik=20H=C3=BCbner?= <[email protected]> Date: Tue, 25 Nov 2025 16:14:17 +0100 Subject: [PATCH 5/8] Update clang/test/CIR/CodeGen/cxx-special-member-attr.cpp Co-authored-by: Andy Kaylor <[email protected]> --- clang/test/CIR/CodeGen/cxx-special-member-attr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp b/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp index cd1377ac04eac..397c72daeadef 100644 --- a/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp +++ b/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp @@ -3,7 +3,7 @@ struct Flub { int a = 123; - // COM: Trivial copy constructors/assignments are replaced with cir.copy + // Trivial copy constructors/assignments are replaced with cir.copy // CIR: cir.copy {{.*}} : !cir.ptr<!rec_Flub> // CIR: @_ZN4FlubC1EOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Flub, move, trivial true> // CIR: @_ZN4FlubaSERKS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) -> !cir.ptr<!rec_Flub> special_member<#cir.cxx_assign<!rec_Flub, copy, trivial true>> From 35283410ccb8199065597dbb498909ee8cba0fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hendrik=20H=C3=BCbner?= <[email protected]> Date: Tue, 25 Nov 2025 16:14:36 +0100 Subject: [PATCH 6/8] Update clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp Co-authored-by: Andy Kaylor <[email protected]> --- clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index a465e6ba04945..53a7cd81e61ec 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -1097,7 +1097,7 @@ void LoweringPreparePass::lowerTrivialCopyCall(cir::CallOp op) { llvm::outs() << "success \n"; // Replace the trivial copy constructor call with a `CopyOp` CIRBaseBuilderTy builder(getContext()); - auto operands = op.getOperands(); + mlir::ValueRange operands = op.getOperands(); mlir::Value dest = operands[0]; mlir::Value src = operands[1]; builder.setInsertionPoint(op); From c2aa41ee1b1f39e2dad34f80ba2189b36f906429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hendrik=20H=C3=BCbner?= <[email protected]> Date: Tue, 25 Nov 2025 16:18:43 +0100 Subject: [PATCH 7/8] Adjust test --- .../CIR/CodeGen/cxx-special-member-attr.cpp | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp b/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp index 397c72daeadef..f2c2c1f683395 100644 --- a/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp +++ b/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp @@ -3,26 +3,15 @@ struct Flub { int a = 123; - // Trivial copy constructors/assignments are replaced with cir.copy - // CIR: cir.copy {{.*}} : !cir.ptr<!rec_Flub> - // CIR: @_ZN4FlubC1EOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Flub, move, trivial true> - // CIR: @_ZN4FlubaSERKS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) -> !cir.ptr<!rec_Flub> special_member<#cir.cxx_assign<!rec_Flub, copy, trivial true>> - // CIR: @_ZN4FlubaSEOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) -> !cir.ptr<!rec_Flub> special_member<#cir.cxx_assign<!rec_Flub, move, trivial true>> }; struct Foo { int a; - // CIR: @_ZN3FooC2Ev(%arg0: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, default>> Foo() : a(123) {} - - // CIR: @_ZN3FooC2ERKS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, copy>> Foo(const Foo &other) : a(other.a) {} - - // CIR: @_ZN3FooC2EOS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, move>> Foo(Foo &&other) noexcept : a(other.a) { other.a = 0; } - // CIR: @_ZN3FooaSERKS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) -> !cir.ptr<!rec_Foo> special_member<#cir.cxx_assign<!rec_Foo, copy>> Foo &operator=(const Foo &other) { if (this != &other) { a = other.a; @@ -30,7 +19,6 @@ struct Foo { return *this; } - // CIR: @_ZN3FooaSEOS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) -> !cir.ptr<!rec_Foo> special_member<#cir.cxx_assign<!rec_Foo, move>> Foo &operator=(Foo &&other) noexcept { if (this != &other) { a = other.a; @@ -39,22 +27,40 @@ struct Foo { return *this; } - // CIR: @_ZN3FooD1Ev(!cir.ptr<!rec_Foo>) special_member<#cir.cxx_dtor<!rec_Foo>> ~Foo(); }; void trivial_func() { Flub f1{}; + Flub f2 = f1; + // Trivial copy constructors/assignments are replaced with cir.copy + // CIR: cir.copy {{.*}} : !cir.ptr<!rec_Flub> + Flub f3 = static_cast<Flub&&>(f1); + // CIR: @_ZN4FlubC1EOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Flub, move, trivial true> + f2 = f1; + // CIR: @_ZN4FlubaSERKS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) -> !cir.ptr<!rec_Flub> special_member<#cir.cxx_assign<!rec_Flub, copy, trivial true>> + f1 = static_cast<Flub&&>(f3); + // CIR: @_ZN4FlubaSEOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) -> !cir.ptr<!rec_Flub> special_member<#cir.cxx_assign<!rec_Flub, move, trivial true>> } void non_trivial_func() { Foo f1{}; + // CIR: @_ZN3FooC2Ev(%arg0: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, default>> + Foo f2 = f1; + // CIR: @_ZN3FooC2ERKS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, copy>> + Foo f3 = static_cast<Foo&&>(f1); + // CIR: @_ZN3FooC2EOS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, move>> + f2 = f1; + // CIR: @_ZN3FooaSERKS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) -> !cir.ptr<!rec_Foo> special_member<#cir.cxx_assign<!rec_Foo, copy>> + f1 = static_cast<Foo&&>(f3); + // CIR: @_ZN3FooaSEOS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) -> !cir.ptr<!rec_Foo> special_member<#cir.cxx_assign<!rec_Foo, move>> + // CIR: @_ZN3FooD1Ev(!cir.ptr<!rec_Foo>) special_member<#cir.cxx_dtor<!rec_Foo>> } From c9e5cbcbdd655b0acba4218c2d01b9493b0c0838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hendrik=20H=C3=BCbner?= <[email protected]> Date: Tue, 2 Dec 2025 18:34:20 +0100 Subject: [PATCH 8/8] Remove debug output for trivial copy constructor Removed debug output for successful trivial copy constructor detection. --- clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index 53a7cd81e61ec..79297babe2b1e 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -1094,7 +1094,6 @@ void LoweringPreparePass::lowerTrivialCopyCall(cir::CallOp op) { std::optional<cir::CtorKind> ctorKind = funcOp.getCxxConstructorKind(); if (ctorKind && *ctorKind == cir::CtorKind::Copy && funcOp.isCxxTrivialMemberFunction()) { - llvm::outs() << "success \n"; // Replace the trivial copy constructor call with a `CopyOp` CIRBaseBuilderTy builder(getContext()); mlir::ValueRange operands = op.getOperands(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
