Skip to content

Commit e5f1d02

Browse files
HendrikHuebnerandykaylorxlauko
authored
[CIR] Lower calls to trivial copy constructor to cir::CopyOp (#168281)
This PR is a follow up to #167975 and replaces calls to trivial copy constructors with `cir::CopyOp`. --------- Co-authored-by: Andy Kaylor <[email protected]> Co-authored-by: Henrich Lauko <[email protected]>
1 parent dbb702f commit e5f1d02

File tree

8 files changed

+73
-45
lines changed

8 files changed

+73
-45
lines changed

clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct LoweringPreparePass
7474
void lowerDynamicCastOp(cir::DynamicCastOp op);
7575
void lowerArrayDtor(cir::ArrayDtor op);
7676
void lowerArrayCtor(cir::ArrayCtor op);
77+
void lowerTrivialCopyCall(cir::CallOp op);
7778

7879
/// Build the function that initializes the specified global
7980
cir::FuncOp buildCXXGlobalVarDeclInitFunc(cir::GlobalOp op);
@@ -1086,6 +1087,25 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor op) {
10861087
true);
10871088
}
10881089

1090+
void LoweringPreparePass::lowerTrivialCopyCall(cir::CallOp op) {
1091+
cir::FuncOp funcOp = getCalledFunction(op);
1092+
if (!funcOp)
1093+
return;
1094+
1095+
std::optional<cir::CtorKind> ctorKind = funcOp.getCxxConstructorKind();
1096+
if (ctorKind && *ctorKind == cir::CtorKind::Copy &&
1097+
funcOp.isCxxTrivialMemberFunction()) {
1098+
// Replace the trivial copy constructor call with a `CopyOp`
1099+
CIRBaseBuilderTy builder(getContext());
1100+
mlir::ValueRange operands = op.getOperands();
1101+
mlir::Value dest = operands[0];
1102+
mlir::Value src = operands[1];
1103+
builder.setInsertionPoint(op);
1104+
builder.createCopy(dest, src);
1105+
op.erase();
1106+
}
1107+
}
1108+
10891109
void LoweringPreparePass::runOnOp(mlir::Operation *op) {
10901110
if (auto arrayCtor = dyn_cast<cir::ArrayCtor>(op)) {
10911111
lowerArrayCtor(arrayCtor);
@@ -1103,6 +1123,8 @@ void LoweringPreparePass::runOnOp(mlir::Operation *op) {
11031123
lowerDynamicCastOp(dynamicCast);
11041124
} else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op)) {
11051125
lowerUnaryOp(unary);
1126+
} else if (auto callOp = dyn_cast<cir::CallOp>(op)) {
1127+
lowerTrivialCopyCall(callOp);
11061128
} else if (auto fnOp = dyn_cast<cir::FuncOp>(op)) {
11071129
if (auto globalCtor = fnOp.getGlobalCtorPriority())
11081130
globalCtorList.emplace_back(fnOp.getName(), globalCtor.value());
@@ -1121,7 +1143,7 @@ void LoweringPreparePass::runOnOperation() {
11211143
op->walk([&](mlir::Operation *op) {
11221144
if (mlir::isa<cir::ArrayCtor, cir::ArrayDtor, cir::CastOp,
11231145
cir::ComplexMulOp, cir::ComplexDivOp, cir::DynamicCastOp,
1124-
cir::FuncOp, cir::GlobalOp, cir::UnaryOp>(op))
1146+
cir::FuncOp, cir::CallOp, cir::GlobalOp, cir::UnaryOp>(op))
11251147
opsToTransform.push_back(op);
11261148
});
11271149

clang/test/CIR/CodeGen/cxx-special-member-attr.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,22 @@
33

44
struct Flub {
55
int a = 123;
6-
// CIR: @_ZN4FlubC1ERKS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Flub, copy, trivial true>>
7-
// CIR: @_ZN4FlubC2EOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Flub, move, trivial true>
8-
// 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>>
9-
// 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>>
106
};
117

128
struct Foo {
139
int a;
1410

15-
// CIR: @_ZN3FooC2Ev(%arg0: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, default>>
1611
Foo() : a(123) {}
17-
18-
// CIR: @_ZN3FooC2ERKS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, copy>>
1912
Foo(const Foo &other) : a(other.a) {}
20-
21-
// CIR: @_ZN3FooC2EOS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, move>>
2213
Foo(Foo &&other) noexcept : a(other.a) { other.a = 0; }
2314

24-
// 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>>
2515
Foo &operator=(const Foo &other) {
2616
if (this != &other) {
2717
a = other.a;
2818
}
2919
return *this;
3020
}
3121

32-
// 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>>
3322
Foo &operator=(Foo &&other) noexcept {
3423
if (this != &other) {
3524
a = other.a;
@@ -38,22 +27,40 @@ struct Foo {
3827
return *this;
3928
}
4029

41-
// CIR: @_ZN3FooD1Ev(!cir.ptr<!rec_Foo>) special_member<#cir.cxx_dtor<!rec_Foo>>
4230
~Foo();
4331
};
4432

45-
void trivial() {
33+
void trivial_func() {
4634
Flub f1{};
35+
4736
Flub f2 = f1;
37+
// Trivial copy constructors/assignments are replaced with cir.copy
38+
// CIR: cir.copy {{.*}} : !cir.ptr<!rec_Flub>
39+
4840
Flub f3 = static_cast<Flub&&>(f1);
41+
// CIR: @_ZN4FlubC1EOS_(%arg0: !cir.ptr<!rec_Flub> loc({{.*}}), %arg1: !cir.ptr<!rec_Flub> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Flub, move, trivial true>
42+
4943
f2 = f1;
44+
// 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>>
45+
5046
f1 = static_cast<Flub&&>(f3);
47+
// 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>>
5148
}
5249

53-
void non_trivial() {
50+
void non_trivial_func() {
5451
Foo f1{};
52+
// CIR: @_ZN3FooC2Ev(%arg0: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, default>>
53+
5554
Foo f2 = f1;
55+
// CIR: @_ZN3FooC2ERKS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, copy>>
56+
5657
Foo f3 = static_cast<Foo&&>(f1);
58+
// CIR: @_ZN3FooC2EOS_(%arg0: !cir.ptr<!rec_Foo> loc({{.*}}), %arg1: !cir.ptr<!rec_Foo> loc({{.*}})) special_member<#cir.cxx_ctor<!rec_Foo, move>>
59+
5760
f2 = f1;
61+
// 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>>
62+
5863
f1 = static_cast<Foo&&>(f3);
64+
// 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>>
65+
// CIR: @_ZN3FooD1Ev(!cir.ptr<!rec_Foo>) special_member<#cir.cxx_dtor<!rec_Foo>>
5966
}

clang/test/CIR/CodeGen/lambda.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ struct A {
367367
// CIR: cir.scope {
368368
// CIR: %[[LAM_ADDR:.*]] = cir.alloca ![[REC_LAM_A]], !cir.ptr<![[REC_LAM_A]]>, ["ref.tmp0"]
369369
// CIR: %[[STRUCT_A:.*]] = cir.get_member %[[LAM_ADDR]][0] {name = "this"} : !cir.ptr<![[REC_LAM_A]]> -> !cir.ptr<!rec_A>
370-
// CIR: cir.call @_ZN1AC1ERKS_(%[[STRUCT_A]], %[[THIS]]){{.*}} : (!cir.ptr<!rec_A>, !cir.ptr<!rec_A>){{.*}} -> ()
370+
// CIR: cir.copy %[[THIS]] to %[[STRUCT_A]] : !cir.ptr<!rec_A>
371371
// CIR: %[[LAM_RET:.*]] = cir.call @_ZZN1A3fooEvENKUlvE_clEv(%[[LAM_ADDR]])
372372
// CIR: cir.store{{.*}} %[[LAM_RET]], %[[RETVAL]]
373373
// CIR: }
@@ -383,7 +383,7 @@ struct A {
383383
// LLVM: br label %[[SCOPE_BB:.*]]
384384
// LLVM: [[SCOPE_BB]]:
385385
// LLVM: %[[STRUCT_A:.*]] = getelementptr %[[REC_LAM_A]], ptr %[[LAM_ALLOCA]], i32 0, i32 0
386-
// LLVM: call void @_ZN1AC1ERKS_(ptr %[[STRUCT_A]], ptr %[[THIS]])
386+
// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[STRUCT_A]], ptr %[[THIS]], i32 4, i1 false)
387387
// LLVM: %[[LAM_RET:.*]] = call i32 @_ZZN1A3fooEvENKUlvE_clEv(ptr %[[LAM_ALLOCA]])
388388
// LLVM: store i32 %[[LAM_RET]], ptr %[[RETVAL]]
389389
// LLVM: br label %[[RET_BB:.*]]

clang/test/CIR/CodeGen/struct.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,13 @@ void paren_expr() {
109109
// CIR: %[[B_ADDR:.*]] = cir.alloca !rec_Point, !cir.ptr<!rec_Point>, ["b", init]
110110
// CIR: %[[CONST:.*]] = cir.const #cir.zero : !rec_Point
111111
// CIR: cir.store{{.*}} %[[CONST]], %[[A_ADDR]] : !rec_Point, !cir.ptr<!rec_Point>
112-
// CIR: cir.call @_ZZ10paren_exprvEN5PointC1ERKS_(%[[B_ADDR]], %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_Point>, !cir.ptr<!rec_Point>) -> ()
112+
// CIR: cir.copy %[[A_ADDR]] to %[[B_ADDR]] : !cir.ptr<!rec_Point>
113113

114114
// LLVM: define{{.*}} void @_Z10paren_exprv()
115115
// LLVM: %[[A_ADDR:.*]] = alloca %struct.Point, i64 1, align 4
116116
// LLVM: %[[B_ADDR:.*]] = alloca %struct.Point, i64 1, align 4
117117
// LLVM: store %struct.Point zeroinitializer, ptr %[[A_ADDR]], align 4
118-
// LLVM: call void @_ZZ10paren_exprvEN5PointC1ERKS_(ptr %[[B_ADDR]], ptr %[[A_ADDR]])
118+
// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[B_ADDR]], ptr %[[A_ADDR]], i32 8, i1 false)
119119

120120
// OGCG: define{{.*}} void @_Z10paren_exprv()
121121
// OGCG: %[[A_ADDR:.*]] = alloca %struct.Point, align 4
@@ -133,14 +133,13 @@ void choose_expr() {
133133
// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a"]
134134
// CIR: %[[B_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["b"]
135135
// CIR: %[[C_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["c", init]
136-
// TODO(cir): Call to default copy constructor should be replaced by `cir.copy` op
137-
// CIR: cir.call @_ZN9CompleteSC1ERKS_(%[[C_ADDR]], %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> ()
136+
// CIR: cir.copy %[[A_ADDR]] to %[[C_ADDR]] : !cir.ptr<!rec_CompleteS>
138137

139138
// LLVM: define{{.*}} void @_Z11choose_exprv()
140139
// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4
141140
// LLVM: %[[B_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4
142141
// LLVM: %[[C_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4
143-
// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %[[C_ADDR]], ptr %[[A_ADDR]])
142+
// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[C_ADDR]], ptr %[[A_ADDR]], i32 8, i1 false)
144143

145144
// OGCG: define{{.*}} void @_Z11choose_exprv()
146145
// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4
@@ -160,15 +159,14 @@ void generic_selection() {
160159
// CIR: %[[B_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["b"]
161160
// CIR: %[[C_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["c"]
162161
// CIR: %[[D_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["d", init]
163-
// TODO(cir): Call to default copy constructor should be replaced by `cir.copy` op
164-
// CIR: cir.call @_ZN9CompleteSC1ERKS_(%[[D_ADDR]], %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> ()
162+
// CIR: cir.copy %[[A_ADDR]] to %[[D_ADDR]] : !cir.ptr<!rec_CompleteS>
165163

166164
// LLVM: define{{.*}} void @_Z17generic_selectionv()
167165
// LLVM: %1 = alloca %struct.CompleteS, i64 1, align 4
168166
// LLVM: %2 = alloca %struct.CompleteS, i64 1, align 4
169167
// LLVM: %3 = alloca i32, i64 1, align 4
170168
// LLVM: %4 = alloca %struct.CompleteS, i64 1, align 4
171-
// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %4, ptr %1)
169+
// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %4, ptr %1, i32 8, i1 false)
172170

173171
// OGCG: define{{.*}} void @_Z17generic_selectionv()
174172
// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4
@@ -188,7 +186,7 @@ void designated_init_update_expr() {
188186
// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a"]
189187
// CIR: %[[B_ADDR:.*]] = cir.alloca !rec_Container, !cir.ptr<!rec_Container>, ["b", init]
190188
// CIR: %[[C_ADDR:.*]] = cir.get_member %[[B_ADDR]][0] {name = "c"} : !cir.ptr<!rec_Container> -> !cir.ptr<!rec_CompleteS>
191-
// CIR: cir.call @_ZN9CompleteSC1ERKS_(%2, %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> ()
189+
// CIR: cir.copy %[[A_ADDR]] to %[[C_ADDR]] : !cir.ptr<!rec_CompleteS>
192190
// CIR: %[[ELEM_0_PTR:.*]] = cir.get_member %[[C_ADDR]][0] {name = "a"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s32i>
193191
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
194192
// CIR: cir.store{{.*}} %[[CONST_1]], %[[ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>
@@ -197,7 +195,7 @@ void designated_init_update_expr() {
197195
// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4
198196
// LLVM: %[[B_ADDR:.*]] = alloca %struct.Container, i64 1, align 4
199197
// LLVM: %[[C_ADDR:.*]] = getelementptr %struct.Container, ptr %[[B_ADDR]], i32 0, i32 0
200-
// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %[[C_ADDR]], ptr %[[A_ADDR]])
198+
// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[C_ADDR]], ptr %[[A_ADDR]], i32 8, i1 false)
201199
// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 0
202200
// LLVM: store i32 1, ptr %[[ELEM_0_PTR]], align 4
203201
// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 1

clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct HasDtor {
4343
// CHECK-NEXT: acc.yield
4444
// CHECK-NEXT: } copy {
4545
// CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NoCopyConstruct> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NoCopyConstruct> {{.*}}):
46-
// CHECK-NEXT: cir.call @_ZN15NoCopyConstructC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_NoCopyConstruct>, !cir.ptr<!rec_NoCopyConstruct>) -> ()
46+
// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_NoCopyConstruct>
4747
// CHECK-NEXT: acc.yield
4848
// CHECK-NEXT: }
4949
//
@@ -63,7 +63,7 @@ struct HasDtor {
6363
// CHECK-NEXT: acc.yield
6464
// CHECK-NEXT: } copy {
6565
// CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}):
66-
// CHECK-NEXT: cir.call @_ZN14NonDefaultCtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_NonDefaultCtor>, !cir.ptr<!rec_NonDefaultCtor>) -> ()
66+
// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_NonDefaultCtor>
6767
// CHECK-NEXT: acc.yield
6868
// CHECK-NEXT: }
6969
//
@@ -73,7 +73,7 @@ struct HasDtor {
7373
// CHECK-NEXT: acc.yield
7474
// CHECK-NEXT: } copy {
7575
// CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}):
76-
// CHECK-NEXT: cir.call @_ZN7HasDtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_HasDtor>, !cir.ptr<!rec_HasDtor>) -> ()
76+
// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_HasDtor>
7777
// CHECK-NEXT: acc.yield
7878
// CHECK-NEXT: } destroy {
7979
// CHECK-NEXT: ^bb0(%[[ORIG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}):
@@ -176,7 +176,7 @@ struct HasDtor {
176176
// CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct>
177177
// CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> -> !cir.ptr<!rec_NoCopyConstruct>
178178
// CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NoCopyConstruct>, !u64i) -> !cir.ptr<!rec_NoCopyConstruct>
179-
// CHECK-NEXT: cir.call @_ZN15NoCopyConstructC1ERKS_(%[[STRIDE_TO]], %[[STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_NoCopyConstruct>, !cir.ptr<!rec_NoCopyConstruct>) -> ()
179+
// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_NoCopyConstruct>
180180
// CHECK-NEXT: cir.yield
181181
// CHECK-NEXT: } step {
182182
// CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i
@@ -246,7 +246,7 @@ struct HasDtor {
246246
// CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NonDefaultCtor>, !u64i) -> !cir.ptr<!rec_NonDefaultCtor>
247247
// CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>> -> !cir.ptr<!rec_NonDefaultCtor>
248248
// CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_NonDefaultCtor>, !u64i) -> !cir.ptr<!rec_NonDefaultCtor>
249-
// CHECK-NEXT: cir.call @_ZN14NonDefaultCtorC1ERKS_(%[[STRIDE_TO]], %[[STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_NonDefaultCtor>, !cir.ptr<!rec_NonDefaultCtor>) -> ()
249+
// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_NonDefaultCtor>
250250
// CHECK-NEXT: cir.yield
251251
// CHECK-NEXT: } step {
252252
// CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i
@@ -281,7 +281,7 @@ struct HasDtor {
281281
// CHECK-NEXT: %[[STRIDE_FROM:.*]] = cir.ptr_stride %[[DECAY_FROM]], %[[ITR_LOAD]] : (!cir.ptr<!rec_HasDtor>, !u64i) -> !cir.ptr<!rec_HasDtor>
282282
// CHECK-NEXT: %[[DECAY_TO:.*]] = cir.cast array_to_ptrdecay %[[ARG_TO]] : !cir.ptr<!cir.array<!rec_HasDtor x 5>> -> !cir.ptr<!rec_HasDtor>
283283
// CHECK-NEXT: %[[STRIDE_TO:.*]] = cir.ptr_stride %[[DECAY_TO]], %[[ITR_LOAD]] : (!cir.ptr<!rec_HasDtor>, !u64i) -> !cir.ptr<!rec_HasDtor>
284-
// CHECK-NEXT: cir.call @_ZN7HasDtorC1ERKS_(%[[STRIDE_TO]], %[[STRIDE_FROM]]) nothrow : (!cir.ptr<!rec_HasDtor>, !cir.ptr<!rec_HasDtor>) -> ()
284+
// CHECK-NEXT: cir.copy %[[STRIDE_FROM]] to %[[STRIDE_TO]] : !cir.ptr<!rec_HasDtor>
285285
// CHECK-NEXT: cir.yield
286286
// CHECK-NEXT: } step {
287287
// CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i

clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct HasDtor {
3030
// CHECK-NEXT: acc.yield
3131
// CHECK-NEXT: } copy {
3232
// CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_NonDefaultCtor> {{.*}}):
33-
// CHECK-NEXT: cir.call @_ZN14NonDefaultCtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_NonDefaultCtor>, !cir.ptr<!rec_NonDefaultCtor>) -> ()
33+
// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_NonDefaultCtor>
3434
// CHECK-NEXT: acc.yield
3535
// CHECK-NEXT: }
3636
//
@@ -40,7 +40,7 @@ struct HasDtor {
4040
// CHECK-NEXT: acc.yield
4141
// CHECK-NEXT: } copy {
4242
// CHECK-NEXT: ^bb0(%[[ARG_FROM:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG_TO:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}):
43-
// CHECK-NEXT: cir.call @_ZN7HasDtorC1ERKS_(%[[ARG_TO]], %[[ARG_FROM]]) nothrow : (!cir.ptr<!rec_HasDtor>, !cir.ptr<!rec_HasDtor>) -> ()
43+
// CHECK-NEXT: cir.copy %[[ARG_FROM]] to %[[ARG_TO]] : !cir.ptr<!rec_HasDtor>
4444
// CHECK-NEXT: acc.yield
4545
// CHECK-NEXT: } destroy {
4646
// CHECK-NEXT: ^bb0(%[[ORIG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}, %[[ARG:.*]]: !cir.ptr<!rec_HasDtor> {{.*}}):

0 commit comments

Comments
 (0)