llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangir Author: Henrich Lauko (xlauko) <details> <summary>Changes</summary> --- Full diff: https://github.com/llvm/llvm-project/pull/186700.diff 9 Files Affected: - (modified) clang/include/clang/CIR/MissingFeatures.h (+1-1) - (modified) clang/lib/CIR/CodeGen/CIRGenClass.cpp (+38-7) - (added) clang/test/CIR/CodeGen/copy-constructor-memcpy.cpp (+41) - (modified) clang/test/CIR/CodeGen/coro-task.cpp (-1) - (modified) clang/test/CIR/CodeGen/cxx-special-member-attr.cpp (+6-5) - (modified) clang/test/CIR/CodeGen/nrvo.cpp (+1-1) - (modified) clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp (-6) - (modified) clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp (-2) - (modified) clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp (-6) ``````````diff diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index b7b4d73afa0f8..f067f621c89a1 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -291,7 +291,6 @@ struct MissingFeatures { static bool instrumentation() { return false; } static bool intrinsicElementTypeSupport() { return false; } static bool intrinsics() { return false; } - static bool isMemcpyEquivalentSpecialMember() { return false; } static bool isTrivialCtorOrDtor() { return false; } static bool lambdaCaptures() { return false; } static bool loopInfoStack() { return false; } @@ -319,6 +318,7 @@ struct MissingFeatures { static bool peepholeProtection() { return false; } static bool pgoUse() { return false; } static bool pointerAuthentication() { return false; } + static bool pointerFieldProtection() { return false; } static bool pointerOverflowSanitizer() { return false; } static bool preservedAccessIndexRegion() { return false; } static bool requiresCleanups() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index 59c6adde7264b..965344975828f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -1278,25 +1278,55 @@ mlir::Value CIRGenFunction::getVTablePtr(mlir::Location loc, Address thisAddr, return vtable; } +// TODO(CIR): This is duplicated from CGClass.cpp. Share between OG and CIR. +static bool isMemcpyEquivalentSpecialMember(CIRGenModule &cgm, + const CXXMethodDecl *d) { + auto *cd = dyn_cast<CXXConstructorDecl>(d); + if (!(cd && cd->isCopyOrMoveConstructor()) && + !d->isCopyAssignmentOperator() && !d->isMoveAssignmentOperator()) + return false; + + // TODO(CIR): OG checks arePFPFieldsTriviallyCopyable / hasPFPFields here. + assert(!cir::MissingFeatures::pointerFieldProtection()); + + // We can emit a memcpy for a trivial copy or move constructor/assignment. + if (d->isTrivial() && !d->getParent()->mayInsertExtraPadding()) + return true; + + // We *must* emit a memcpy for a defaulted union copy or move op. + if (d->getParent()->isUnion() && d->isDefaulted()) + return true; + + return false; +} + void CIRGenFunction::emitCXXConstructorCall(const clang::CXXConstructorDecl *d, clang::CXXCtorType type, bool forVirtualBase, bool delegating, AggValueSlot thisAVS, const clang::CXXConstructExpr *e) { - CallArgList args; Address thisAddr = thisAVS.getAddress(); QualType thisType = d->getThisType(); mlir::Value thisPtr = thisAddr.getPointer(); assert(!cir::MissingFeatures::addressSpace()); - args.add(RValue::get(thisPtr), thisType); + // If this is a trivial constructor, just emit what's needed. If this is a + // union copy constructor, we must emit a memcpy, because the AST does not + // model that copy. + if (isMemcpyEquivalentSpecialMember(cgm, d)) { + assert(e->getNumArgs() == 1 && "unexpected argcount for trivial ctor"); + const Expr *arg = e->getArg(0); + LValue src = emitLValue(arg); + CanQualType destTy = getContext().getCanonicalTagType(d->getParent()); + LValue dest = makeAddrLValue(thisAddr, destTy); + emitAggregateCopy(dest, src, src.getType(), thisAVS.mayOverlap()); + return; + } - // In LLVM Codegen: If this is a trivial constructor, just emit what's needed. - // If this is a union copy constructor, we must emit a memcpy, because the AST - // does not model that copy. - assert(!cir::MissingFeatures::isMemcpyEquivalentSpecialMember()); + CallArgList args; + args.add(RValue::get(thisPtr), thisType); const FunctionProtoType *fpt = d->getType()->castAs<FunctionProtoType>(); @@ -1322,7 +1352,8 @@ void CIRGenFunction::emitCXXConstructorCall( // ctor call into trivial initialization. assert(!cir::MissingFeatures::isTrivialCtorOrDtor()); - assert(!cir::MissingFeatures::isMemcpyEquivalentSpecialMember()); + // Note: memcpy-equivalent special members are handled in the + // emitCXXConstructorCall overload that takes a CXXConstructExpr. bool passPrototypeArgs = true; diff --git a/clang/test/CIR/CodeGen/copy-constructor-memcpy.cpp b/clang/test/CIR/CodeGen/copy-constructor-memcpy.cpp new file mode 100644 index 0000000000000..d7b141cd91bc9 --- /dev/null +++ b/clang/test/CIR/CodeGen/copy-constructor-memcpy.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu \ +// RUN: -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu \ +// RUN: -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu \ +// RUN: -emit-llvm %s -o %t.og.ll +// RUN: FileCheck --check-prefix=OGCG --input-file=%t.og.ll %s + +// Test that trivial copy constructors are inlined as aggregate copies +// (memcpy-equivalent special members) rather than emitted as function calls. + +struct S { + int a; + int b; +}; + +struct W { + S s; + W(const S &src) : s(src) {} +}; + +void test(const S &src) { + W w(src); +} + +// The copy of S in W's constructor should be inlined as cir.copy, +// not a call to S's copy constructor. + +// CIR-LABEL: cir.func{{.*}} @_ZN1WC2ERK1S +// CIR-NOT: cir.call @_ZN1SC +// CIR: cir.copy %{{.+}} to %{{.+}} : !cir.ptr<!rec_S> + +// Both CIR-lowered LLVM and OG produce memcpy for the inlined copy. + +// LLVM-LABEL: define{{.*}} void @_ZN1WC2ERK1S +// LLVM: call void @llvm.memcpy.p0.p0.i64({{.*}}i64 8 + +// OGCG-LABEL: define{{.*}} void @_ZN1WC2ERK1S +// OGCG: call void @llvm.memcpy.p0.p0.i64({{.*}}i64 8 diff --git a/clang/test/CIR/CodeGen/coro-task.cpp b/clang/test/CIR/CodeGen/coro-task.cpp index b52f0f1871079..568dedf2c7921 100644 --- a/clang/test/CIR/CodeGen/coro-task.cpp +++ b/clang/test/CIR/CodeGen/coro-task.cpp @@ -430,7 +430,6 @@ folly::coro::Task<void> yield1() { // yield_value + await(yield) // CIR: %[[YIELD_TASK:.*]] = cir.call @_Z5yieldv(){{.*}} // CIR: cir.store{{.*}} %[[YIELD_TASK]], %[[T_ADDR]] -// CIR: cir.copy %[[T_ADDR]] to %[[AWAITER_COPY_ADDR]] // CIR: %[[AWAITER:.*]] = cir.load{{.*}} %[[AWAITER_COPY_ADDR]] // CIR: %[[YIELD_SUSP:.*]] = cir.call @_ZN5folly4coro4TaskIvE12promise_type11yield_valueES2_(%[[PROMISE]], %[[AWAITER]]){{.*}} // CIR: cir.store{{.*}} %[[YIELD_SUSP]], %[[SUSP1]] diff --git a/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp b/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp index a68d8a5d48209..bfca59db44fdf 100644 --- a/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp +++ b/clang/test/CIR/CodeGen/cxx-special-member-attr.cpp @@ -30,21 +30,22 @@ struct Foo { ~Foo(); }; +// Trivial copy/move assignment operator definitions appear at module level. +// 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>> + void trivial_func() { Flub f1{}; Flub f2 = f1; - // Trivial copy constructors/assignments are replaced with cir.copy + // Trivial copy/move constructors are inlined as 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> + // CIR: cir.copy {{.*}} : !cir.ptr<!rec_Flub> 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() { diff --git a/clang/test/CIR/CodeGen/nrvo.cpp b/clang/test/CIR/CodeGen/nrvo.cpp index a3af2d1ff032b..08aad0723d331 100644 --- a/clang/test/CIR/CodeGen/nrvo.cpp +++ b/clang/test/CIR/CodeGen/nrvo.cpp @@ -32,7 +32,7 @@ struct S f1() { // CIR-NOELIDE-NEXT: %[[RETVAL:.*]] = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["__retval"] // CIR-NOELIDE-NEXT: %[[S:.*]] = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["s", init] // CIR-NOELIDE-NEXT: cir.call @_ZN1SC1Ev(%[[S]]) : (!cir.ptr<!rec_S> {{.*}}) -> () -// CIR-NOELIDE-NEXT: cir.call @_ZN1SC1EOS_(%[[RETVAL]], %[[S]]){{.*}} : (!cir.ptr<!rec_S> {{.*}}, !cir.ptr<!rec_S> {{.*}}) -> () +// CIR-NOELIDE-NEXT: cir.copy %[[S]] to %[[RETVAL]] : !cir.ptr<!rec_S> // CIR-NOELIDE-NEXT: %[[RET:.*]] = cir.load %[[RETVAL]] : !cir.ptr<!rec_S>, !rec_S // CIR-NOELIDE-NEXT: cir.return %[[RET]] diff --git a/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp b/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp index 0a67314a91b07..5c48fb3088431 100644 --- a/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp +++ b/clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp @@ -43,7 +43,6 @@ 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_TO]] : !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // @@ -63,7 +62,6 @@ 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: acc.yield // CHECK-NEXT: } // @@ -73,7 +71,6 @@ 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.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 +173,6 @@ 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.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i @@ -246,7 +242,6 @@ 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.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 +276,6 @@ 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.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 62fb6528ffdfe..ad5109c0308af 100644 --- a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp +++ b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp @@ -30,7 +30,6 @@ 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: acc.yield // CHECK-NEXT: } // @@ -40,7 +39,6 @@ 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.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 c4cec3023e046..033dc4cef1134 100644 --- a/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp +++ b/clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp @@ -44,7 +44,6 @@ 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_TO]] : !cir.ptr<!rec_NoCopyConstruct> // CHECK-NEXT: acc.yield // CHECK-NEXT: } // @@ -64,7 +63,6 @@ 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: acc.yield // CHECK-NEXT: } // @@ -74,7 +72,6 @@ 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.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> {{.*}}): @@ -177,7 +174,6 @@ 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.yield // CHECK-NEXT: } step { // CHECK-NEXT: %[[ITR_LOAD]] = cir.load %[[ITR]] : !cir.ptr<!u64i>, !u64i @@ -247,7 +243,6 @@ 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.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 @@ -282,7 +277,6 @@ 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.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 `````````` </details> https://github.com/llvm/llvm-project/pull/186700 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
