Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,13 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return cir::AllocaOp::create(*this, loc, addrType, type, name, alignment);
}

mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
mlir::Type type, llvm::StringRef name,
clang::CharUnits alignment) {
mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
return createAlloca(loc, addrType, type, name, alignmentAttr);
}

/// Get constant address of a global variable as an MLIR attribute.
/// This wrapper infers the attribute type through the global op.
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp,
Expand Down
112 changes: 111 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
//
//===----------------------------------------------------------------------===//

#include <numeric>

#include "CIRGenOpenACCRecipe.h"

namespace clang::CIRGen {
Expand All @@ -35,6 +37,110 @@ mlir::Block *OpenACCRecipeBuilderBase::createRecipeBlock(mlir::Region &region,
return builder.createBlock(&region, region.end(), types, locs);
}

mlir::Value OpenACCRecipeBuilderBase::makeBoundsAlloca(
mlir::Block *block, SourceRange exprRange, mlir::Location loc,
std::string_view allocaName, size_t numBounds,
llvm::ArrayRef<QualType> boundTypes) {
mlir::OpBuilder::InsertionGuard guardCase(builder);

// Get the range of bounds arguments, which are all but the 1st arg.
llvm::ArrayRef<mlir::BlockArgument> boundsRange =
block->getArguments().drop_front(1);

// boundTypes contains the before and after of each bounds, so it ends up
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still not completely clear on the why here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I basically need all of the types for one reason or another, both before and after each 'bounds' operation depending on what we need. SO I just store them all in boundTypes. For example, the 'top level' allocation happens at the least-bounded type. See 84 and 89 for cases where we need the first-set or second set (befores vs afters).

Consider: A[N]:: 1 bound operation, 2 types (type of A, and type of an element of A). Or: A[N][M]: 2 bound operations, 3 types, etc.

The assert is a sanity check for me on that case.

Or is there something else I can clarify? I know I was a little verbose in my comments (I kept losing my way getting this right), so perhaps I wrote something confusing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.

// having 1 extra. Assert this is the case to ensure we don't call this in the
// wrong 'block'.
assert(boundsRange.size() + 1 == boundTypes.size());

mlir::Type itrTy = cgf.cgm.convertType(cgf.getContext().UnsignedLongLongTy);
auto idxType = mlir::IndexType::get(&cgf.getMLIRContext());

auto getUpperBound = [&](mlir::Value bound) {
auto upperBoundVal =
mlir::acc::GetUpperboundOp::create(builder, loc, idxType, bound);
return mlir::UnrealizedConversionCastOp::create(builder, loc, itrTy,
upperBoundVal.getResult())
.getResult(0);
};

auto isArrayTy = [&](QualType ty) {
if (ty->isArrayType() && !ty->isConstantArrayType())
cgf.cgm.errorNYI(exprRange, "OpenACC recipe init for VLAs");
return ty->isConstantArrayType();
};

mlir::Type topLevelTy = cgf.convertType(boundTypes.back());
cir::PointerType topLevelTyPtr = builder.getPointerTo(topLevelTy);
// Do an alloca for the 'top' level type without bounds.
mlir::Value initialAlloca = builder.createAlloca(
loc, topLevelTyPtr, topLevelTy, allocaName,
cgf.getContext().getTypeAlignInChars(boundTypes.back()));

bool lastBoundWasArray = isArrayTy(boundTypes.back());

// Since we're iterating the types in reverse, this sets up for each index
// corresponding to the boundsRange to be the 'after application of the
// bounds.
llvm::ArrayRef<QualType> boundResults = boundTypes.drop_back(1);

// Collect the 'do we have any allocas needed after this type' list.
llvm::SmallVector<bool> allocasLeftArr;
llvm::ArrayRef<QualType> resultTypes = boundTypes.drop_front();
std::transform_inclusive_scan(
resultTypes.begin(), resultTypes.end(),
std::back_inserter(allocasLeftArr), std::plus<bool>{},
[](QualType ty) { return !ty->isConstantArrayType(); });

Comment on lines +89 to +93
Copy link
Member

@AmrDeveloper AmrDeveloper Sep 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I misunderstood something, but I think this part will not compile, from the header file, this part will report a type mismatch error ->

typename iterator_traits<_InputIterator>::value_type __init = __u(*__first);

iterator_traits<_InputIterator>::value_type -> QualType
lambda(*resultTypes.begin()) -> bool

QualType __init = bool;

Error message

error: no viable conversion from 'bool' to 'typename iterator_traits<__wrap_iter<QualType *>>::value_type' (aka 'QualType')

I don't know why in transform_inclusive_scan we expected that the init value type is the same value type as the Input iterator, not the Output iterator 🤔 😕

The code will compile if we use the other overloading version of transform_inclusive_scan that takes init as parameter, and we can pass true or false

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@erichkeane I just encountered the same compilation error. As @AmrDeveloper says the default parameter fixes this: #161428

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is strange, it compiles for me! I wonder if the lookup/etc rules have changed or are just different in our compilers. Thank you for the patch, I'll look at it ASAP.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks you two! I looked at the review, that is fine.

It appears to be a mistake in the library, I suspect they're copying the restriction from transform_exclusive_scan.

// Keep track of the number of 'elements' that we're allocating. Individual
// allocas should multiply this by the size of its current allocation.
mlir::Value cumulativeElts;
for (auto [bound, resultType, allocasLeft] : llvm::reverse(
llvm::zip_equal(boundsRange, boundResults, allocasLeftArr))) {

// if there is no further 'alloca' operation we need to do, we can skip
// creating the UB/multiplications/etc.
if (!allocasLeft)
break;

// First: figure out the number of elements in the current 'bound' list.
mlir::Value eltsPerSubArray = getUpperBound(bound);
mlir::Value eltsToAlloca;

// IF we are in a sub-bounds, the total number of elements to alloca is
// the product of that one and the current 'bounds' size. That is,
// arr[5][5], we would need 25 elements, not just 5. Else it is just the
// current number of elements.
if (cumulativeElts)
eltsToAlloca = builder.createMul(loc, eltsPerSubArray, cumulativeElts);
else
eltsToAlloca = eltsPerSubArray;

if (!lastBoundWasArray) {
// If we have to do an allocation, figure out the size of the
// allocation. alloca takes the number of bytes, not elements.
TypeInfoChars eltInfo = cgf.getContext().getTypeInfoInChars(resultType);
cir::ConstantOp eltSize = builder.getConstInt(
loc, itrTy, eltInfo.Width.alignTo(eltInfo.Align).getQuantity());
mlir::Value curSize = builder.createMul(loc, eltsToAlloca, eltSize);

mlir::Type eltTy = cgf.convertType(resultType);
cir::PointerType ptrTy = builder.getPointerTo(eltTy);
builder.createAlloca(loc, ptrTy, eltTy, "openacc.init.bounds",
cgf.getContext().getTypeAlignInChars(resultType),
curSize);

// TODO: OpenACC : At this point we should be copying the addresses of
// each element of this to the last allocation. At the moment, that is
// not yet implemented.
cgf.cgm.errorNYI(exprRange, "OpenACC recipe alloca copying");
}

cumulativeElts = eltsToAlloca;
lastBoundWasArray = isArrayTy(resultType);
}
return initialAlloca;
}

mlir::Value
OpenACCRecipeBuilderBase::createBoundsLoop(mlir::Value subscriptedValue,
mlir::Value bound,
Expand Down Expand Up @@ -258,7 +364,11 @@ void OpenACCRecipeBuilderBase::createPrivateInitRecipe(
cgf.emitAutoVarAlloca(*allocaDecl, builder.saveInsertionPoint());
cgf.emitAutoVarInit(tempDeclEmission);
} else {
cgf.cgm.errorNYI(exprRange, "private-init with bounds");
makeBoundsAlloca(block, exprRange, loc, "openacc.private.init", numBounds,
boundTypes);

if (initExpr)
cgf.cgm.errorNYI(exprRange, "private-init with bounds initialization");
}

mlir::acc::YieldOp::create(builder, locEnd);
Expand Down
32 changes: 10 additions & 22 deletions clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@

namespace clang::CIRGen {
class OpenACCRecipeBuilderBase {
// This function generates the required alloca, similar to
// 'emitAutoVarAlloca', except for the OpenACC array/pointer types.
mlir::Value makeBoundsAlloca(mlir::Block *block, SourceRange exprRange,
mlir::Location loc, std::string_view allocaName,
size_t numBounds,
llvm::ArrayRef<QualType> boundTypes);

protected:
CIRGen::CIRGenFunction &cgf;
CIRGen::CIRGenBuilderTy &builder;
Expand Down Expand Up @@ -165,28 +172,9 @@ class OpenACCRecipeBuilder : OpenACCRecipeBuilderBase {
cgf.emitAutoVarAlloca(*varRecipe, builder.saveInsertionPoint());

// 'firstprivate' doesn't do its initialization in the 'init' section,
// instead does it in the 'copy' section. SO only do init here.
// 'reduction' appears to use it too (rather than a 'copy' section), so
// we probably have to do it here too, but we can do that when we get to
// reduction implementation.
if constexpr (std::is_same_v<RecipeTy, mlir::acc::PrivateRecipeOp>) {
// We are OK with no init for builtins, arrays of builtins, or pointers,
// else we should NYI so we know to go look for these.
if (cgf.getContext().getLangOpts().CPlusPlus &&
!varRecipe->getType()
->getPointeeOrArrayElementType()
->isBuiltinType() &&
!varRecipe->getType()->isPointerType() && !varRecipe->getInit()) {
// If we don't have any initialization recipe, we failed during Sema to
// initialize this correctly. If we disable the
// Sema::TentativeAnalysisScopes in SemaOpenACC::CreateInitRecipe, it'll
// emit an error to tell us. However, emitting those errors during
// production is a violation of the standard, so we cannot do them.
cgf.cgm.errorNYI(exprRange, "private default-init recipe");
}
cgf.emitAutoVarInit(tempDeclEmission);
} else if constexpr (std::is_same_v<RecipeTy,
mlir::acc::ReductionRecipeOp>) {
// instead it does it in the 'copy' section. SO, only do 'init' here for
// reduction.
if constexpr (std::is_same_v<RecipeTy, mlir::acc::ReductionRecipeOp>) {
// Unlike Private, the recipe here is always required as it has to do
// init, not just 'default' init.
if (!varRecipe->getInit())
Expand Down
6 changes: 6 additions & 0 deletions clang/test/CIR/CodeGenOpenACC/combined-private-clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,41 +65,47 @@ struct HasDtor {
// int[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_i : !cir.ptr<!cir.array<!s32i x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!s32i x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!s32i x 5>, !cir.ptr<!cir.array<!s32i x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// float[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_f : !cir.ptr<!cir.array<!cir.float x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!cir.float x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!cir.float x 5>, !cir.ptr<!cir.array<!cir.float x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// NoCopyConstruct[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_15NoCopyConstruct : !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_NoCopyConstruct x 5>, !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// CopyConstruct[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_13CopyConstruct : !cir.ptr<!cir.array<!rec_CopyConstruct x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_CopyConstruct x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_CopyConstruct x 5>, !cir.ptr<!cir.array<!rec_CopyConstruct x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// NonDefaultCtor[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_14NonDefaultCtor : !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_NonDefaultCtor x 5>, !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// HasDtor[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_7HasDtor : !cir.ptr<!cir.array<!rec_HasDtor x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_HasDtor x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_HasDtor x 5>, !cir.ptr<!cir.array<!rec_HasDtor x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: } destroy {
Expand Down
5 changes: 4 additions & 1 deletion clang/test/CIR/CodeGenOpenACC/compute-private-clause.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: not %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 - | FileCheck %s

struct NoCopyConstruct {};

Expand Down Expand Up @@ -26,20 +26,23 @@ struct NoCopyConstruct {};
// int[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_i : !cir.ptr<!cir.array<!s32i x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!s32i x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!s32i x 5>, !cir.ptr<!cir.array<!s32i x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// float[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_f : !cir.ptr<!cir.array<!cir.float x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!cir.float x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!cir.float x 5>, !cir.ptr<!cir.array<!cir.float x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// NoCopyConstruct[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_15NoCopyConstruct : !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_NoCopyConstruct x 5>, !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
Expand Down
6 changes: 6 additions & 0 deletions clang/test/CIR/CodeGenOpenACC/compute-private-clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,36 +58,42 @@ struct HasDtor {
//
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_i : !cir.ptr<!cir.array<!s32i x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!s32i x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!s32i x 5>, !cir.ptr<!cir.array<!s32i x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_f : !cir.ptr<!cir.array<!cir.float x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!cir.float x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!cir.float x 5>, !cir.ptr<!cir.array<!cir.float x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_15NoCopyConstruct : !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_NoCopyConstruct x 5>, !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_13CopyConstruct : !cir.ptr<!cir.array<!rec_CopyConstruct x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_CopyConstruct x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_CopyConstruct x 5>, !cir.ptr<!cir.array<!rec_CopyConstruct x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_14NonDefaultCtor : !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_NonDefaultCtor x 5>, !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// CHECK: acc.private.recipe @privatization__Bcnt1__ZTSA5_7HasDtor : !cir.ptr<!cir.array<!rec_HasDtor x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_HasDtor x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_HasDtor x 5>, !cir.ptr<!cir.array<!rec_HasDtor x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: } destroy {
Expand Down
6 changes: 6 additions & 0 deletions clang/test/CIR/CodeGenOpenACC/loop-private-clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,41 +65,47 @@ struct HasDtor {
// int[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_i : !cir.ptr<!cir.array<!s32i x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!s32i x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!s32i x 5>, !cir.ptr<!cir.array<!s32i x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// float[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_f : !cir.ptr<!cir.array<!cir.float x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!cir.float x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!cir.float x 5>, !cir.ptr<!cir.array<!cir.float x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// NoCopyConstruct[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_15NoCopyConstruct : !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_NoCopyConstruct x 5>, !cir.ptr<!cir.array<!rec_NoCopyConstruct x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// CopyConstruct[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_13CopyConstruct : !cir.ptr<!cir.array<!rec_CopyConstruct x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_CopyConstruct x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_CopyConstruct x 5>, !cir.ptr<!cir.array<!rec_CopyConstruct x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// NonDefaultCtor[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_14NonDefaultCtor : !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_NonDefaultCtor x 5>, !cir.ptr<!cir.array<!rec_NonDefaultCtor x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
//
// HasDtor[5] with 1 'bound'
// CHECK-NEXT: acc.private.recipe @privatization__Bcnt1__ZTSA5_7HasDtor : !cir.ptr<!cir.array<!rec_HasDtor x 5>> init {
// CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_HasDtor x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}):
// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_HasDtor x 5>, !cir.ptr<!cir.array<!rec_HasDtor x 5>>, ["openacc.private.init"]
// TODO: Add Init here.
// CHECK-NEXT: acc.yield
// CHECK-NEXT: } destroy {
Expand Down
Loading
Loading