mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 14:48:27 +08:00
[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 <akaylor@nvidia.com> Co-authored-by: Henrich Lauko <henrich.lau@gmail.com>
This commit is contained in:
@@ -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);
|
||||
@@ -1086,6 +1087,25 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor op) {
|
||||
true);
|
||||
}
|
||||
|
||||
void LoweringPreparePass::lowerTrivialCopyCall(cir::CallOp op) {
|
||||
cir::FuncOp funcOp = getCalledFunction(op);
|
||||
if (!funcOp)
|
||||
return;
|
||||
|
||||
std::optional<cir::CtorKind> ctorKind = funcOp.getCxxConstructorKind();
|
||||
if (ctorKind && *ctorKind == cir::CtorKind::Copy &&
|
||||
funcOp.isCxxTrivialMemberFunction()) {
|
||||
// Replace the trivial copy constructor call with a `CopyOp`
|
||||
CIRBaseBuilderTy builder(getContext());
|
||||
mlir::ValueRange 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);
|
||||
@@ -1103,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());
|
||||
@@ -1121,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);
|
||||
});
|
||||
|
||||
|
||||
@@ -3,25 +3,15 @@
|
||||
|
||||
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>
|
||||
// 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;
|
||||
@@ -29,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;
|
||||
@@ -38,22 +27,40 @@ struct Foo {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// CIR: @_ZN3FooD1Ev(!cir.ptr<!rec_Foo>) special_member<#cir.cxx_dtor<!rec_Foo>>
|
||||
~Foo();
|
||||
};
|
||||
|
||||
void trivial() {
|
||||
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() {
|
||||
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>>
|
||||
}
|
||||
|
||||
@@ -367,7 +367,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: }
|
||||
@@ -383,7 +383,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:.*]]
|
||||
|
||||
@@ -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.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
|
||||
// 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
|
||||
|
||||
@@ -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: }
|
||||
//
|
||||
@@ -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.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
|
||||
@@ -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
|
||||
|
||||
@@ -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: }
|
||||
//
|
||||
@@ -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> {{.*}}):
|
||||
|
||||
@@ -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 {};
|
||||
|
||||
@@ -43,7 +44,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 +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.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 +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.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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user