llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Erich Keane (erichkeane)

<details>
<summary>Changes</summary>

These four operators have an initial value of 0, so they are able to use C/C++ 
'zero init'.  This patch adds the infrastructure to the Sema init calculations 
to differentiate based on the reduction operator, then enables emission of the 
inits in CodeGen (which should work for all
    inits, once generated).

The rest of this test is just updating validation to make sure that the inits 
happen correctly for all 4 operators.

---

Patch is 366.11 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/155924.diff


23 Files Affected:

- (modified) clang/include/clang/Sema/SemaOpenACC.h (+8-1) 
- (modified) clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp (+15-7) 
- (modified) clang/lib/Sema/SemaOpenACC.cpp (+47-2) 
- (modified) clang/lib/Sema/SemaOpenACCClause.cpp (+3-2) 
- (modified) clang/lib/Sema/TreeTransform.h (+5-5) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp 
(+196-16) 
- (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-float.cpp 
(+120-16) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-inline-ops.cpp 
(+200-20) 
- (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-int.cpp 
(+112-16) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-outline-ops.cpp 
(+200-20) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-default-ops.c (+168-16) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-default-ops.cpp 
(+197-16) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-float.c 
(+120-16) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-float.cpp 
(+120-16) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-inline-ops.cpp (+200-20) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-int.c 
(+112-16) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-int.cpp 
(+109-16) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-outline-ops.cpp 
(+200-20) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-default-ops.cpp (+196-16) 
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-float.cpp 
(+120-16) 
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-inline-ops.cpp 
(+200-20) 
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-int.cpp 
(+112-16) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-outline-ops.cpp (+200-20) 


``````````diff
diff --git a/clang/include/clang/Sema/SemaOpenACC.h 
b/clang/include/clang/Sema/SemaOpenACC.h
index e7b62aafc060b..42e86582c3b06 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -244,7 +244,14 @@ class SemaOpenACC : public SemaBase {
   //  'temporary' created for the init (in the case of a copy), such as with
   //  firstprivate.
   std::pair<VarDecl *, VarDecl *> CreateInitRecipe(OpenACCClauseKind CK,
-                                                   const Expr *VarExpr);
+                                                   const Expr *VarExpr) {
+    assert(CK != OpenACCClauseKind::Reduction);
+    return CreateInitRecipe(CK, OpenACCReductionOperator::Invalid, VarExpr);
+  }
+  std::pair<VarDecl *, VarDecl *>
+  CreateInitRecipe(OpenACCClauseKind CK,
+                   OpenACCReductionOperator ReductionOperator,
+                   const Expr *VarExpr);
 
 public:
   ComputeConstructInfo &getActiveComputeConstructInfo() {
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp 
b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
index 0f2ca2dbe75c7..37533368af4b2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
@@ -425,6 +425,7 @@ class OpenACCClauseCIREmitter final
         &recipe.getCopyRegion(), recipe.getCopyRegion().end(),
         {mainOp.getType(), mainOp.getType()}, {loc, loc});
     builder.setInsertionPointToEnd(&recipe.getCopyRegion().back());
+    CIRGenFunction::LexicalScope ls(cgf, loc, block);
 
     mlir::BlockArgument fromArg = block->getArgument(0);
     mlir::BlockArgument toArg = block->getArgument(1);
@@ -457,11 +458,6 @@ class OpenACCClauseCIREmitter final
                             RecipeTy recipe, const VarDecl *varRecipe,
                             const VarDecl *temporary) {
     assert(varRecipe && "Required recipe variable not set?");
-    if constexpr (std::is_same_v<RecipeTy, mlir::acc::ReductionRecipeOp>) {
-      // We haven't implemented the 'init' recipe for Reduction yet, so NYI
-      // it.
-      cgf.cgm.errorNYI(exprRange, "OpenACC Reduction recipe init");
-    }
 
     CIRGenFunction::AutoVarEmission tempDeclEmission{
         CIRGenFunction::AutoVarEmission::invalid()};
@@ -469,9 +465,12 @@ class OpenACCClauseCIREmitter final
 
     // Do the 'init' section of the recipe IR, which does an alloca, then the
     // initialization (except for firstprivate).
-    builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(),
-                        {mainOp.getType()}, {loc});
+    mlir::Block *block = builder.createBlock(&recipe.getInitRegion(),
+                                             recipe.getInitRegion().end(),
+                                             {mainOp.getType()}, {loc});
     builder.setInsertionPointToEnd(&recipe.getInitRegion().back());
+    CIRGenFunction::LexicalScope ls(cgf, loc, block);
+
     tempDeclEmission =
         cgf.emitAutoVarAlloca(*varRecipe, builder.saveInsertionPoint());
 
@@ -496,6 +495,13 @@ class OpenACCClauseCIREmitter final
         cgf.cgm.errorNYI(exprRange, "private default-init recipe");
       }
       cgf.emitAutoVarInit(tempDeclEmission);
+    } else 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())
+        cgf.cgm.errorNYI(exprRange, "reduction init recipe");
+      cgf.emitAutoVarInit(tempDeclEmission);
     }
 
     mlir::acc::YieldOp::create(builder, locEnd);
@@ -527,6 +533,7 @@ class OpenACCClauseCIREmitter final
         &recipe.getCombinerRegion(), recipe.getCombinerRegion().end(),
         {mainOp.getType(), mainOp.getType()}, {loc, loc});
     builder.setInsertionPointToEnd(&recipe.getCombinerRegion().back());
+    CIRGenFunction::LexicalScope ls(cgf, loc, block);
 
     mlir::BlockArgument lhsArg = block->getArgument(0);
 
@@ -544,6 +551,7 @@ class OpenACCClauseCIREmitter final
     mlir::Block *block = builder.createBlock(
         &destroyRegion, destroyRegion.end(), {mainOp.getType()}, {loc});
     builder.setInsertionPointToEnd(&destroyRegion.back());
+    CIRGenFunction::LexicalScope ls(cgf, loc, block);
 
     mlir::Type elementTy =
         mlir::cast<cir::PointerType>(mainOp.getType()).getPointee();
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 1457522406531..5386682b3a991 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2590,7 +2590,9 @@ SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation 
AsteriskLoc) {
 }
 
 std::pair<VarDecl *, VarDecl *>
-SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK, const Expr *VarExpr) {
+SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
+                              OpenACCReductionOperator ReductionOperator,
+                              const Expr *VarExpr) {
   // Strip off any array subscripts/array section exprs to get to the type of
   // the variable.
   while (isa_and_present<ArraySectionExpr, ArraySubscriptExpr>(VarExpr)) {
@@ -2722,7 +2724,50 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK, 
const Expr *VarExpr) {
                                      /*TreatUnavailableAsInvalid=*/false);
       Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, InitExpr, &VarTy);
     } else if (CK == OpenACCClauseKind::Reduction) {
-      // TODO: OpenACC: Implement this for whatever reduction needs.
+      // How we initialize the reduction variable depends on the operator used,
+      // according to the chart in OpenACC 3.3 section 2.6.15.
+
+      switch (ReductionOperator) {
+      case OpenACCReductionOperator::Invalid:
+        // This can only happen when there is an error, and since these inits
+        // are used for code generation, we can just ignore/not bother doing 
any
+        // initialization here.
+        break;
+      case OpenACCReductionOperator::Multiplication:
+      case OpenACCReductionOperator::Max:
+      case OpenACCReductionOperator::Min:
+      case OpenACCReductionOperator::BitwiseAnd:
+      case OpenACCReductionOperator::And:
+        // TODO: OpenACC: figure out init for these.
+        break;
+
+      case OpenACCReductionOperator::Addition:
+      case OpenACCReductionOperator::BitwiseOr:
+      case OpenACCReductionOperator::BitwiseXOr:
+      case OpenACCReductionOperator::Or: {
+        // +, |, ^, and || all use 0 for their initializers, so we can just
+        // use 'zero init' here and not bother with the rest of the
+        // array/compound type/etc contents.
+        auto *Zero = IntegerLiteral::Create(
+            getASTContext(),
+            llvm::APInt(getASTContext().getTypeSize(getASTContext().IntTy), 0),
+            getASTContext().IntTy, VarExpr->getBeginLoc());
+        Expr *InitExpr = new (getASTContext())
+            InitListExpr(getASTContext(), VarExpr->getBeginLoc(), Zero,
+                         VarExpr->getEndLoc());
+        // we set this to void so that the initialization sequence generation
+        // will get this type correct/etc.
+        InitExpr->setType(getASTContext().VoidTy);
+
+        InitializationKind Kind = InitializationKind::CreateForInit(
+            Recipe->getLocation(), /*DirectInit=*/true, InitExpr);
+        InitializationSequence InitSeq(SemaRef.SemaRef, Entity, Kind, InitExpr,
+                                       /*TopLevelOfInitList=*/false,
+                                       /*TreatUnavailableAsInvalid=*/false);
+        Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, InitExpr, 
&VarTy);
+        break;
+      }
+      }
     } else {
       llvm_unreachable("Unknown clause kind in CreateInitRecipe");
     }
diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp 
b/clang/lib/Sema/SemaOpenACCClause.cpp
index 43ae4f4d3011c..677b74fb4e336 100644
--- a/clang/lib/Sema/SemaOpenACCClause.cpp
+++ b/clang/lib/Sema/SemaOpenACCClause.cpp
@@ -1784,9 +1784,10 @@ OpenACCClause 
*SemaOpenACCClauseVisitor::VisitReductionClause(
       ValidVars.push_back(Res.get());
 
       VarDecl *InitRecipe =
-          SemaRef.CreateInitRecipe(OpenACCClauseKind::Reduction, Res.get())
+          SemaRef
+              .CreateInitRecipe(OpenACCClauseKind::Reduction,
+                                Clause.getReductionOp(), Res.get())
               .first;
-      // TODO: OpenACC: Create the reduction operation recipe here too.
       Recipes.push_back({InitRecipe});
     }
   }
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 827e568c83b38..aa1bb3232d6fa 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12430,11 +12430,11 @@ void 
OpenACCClauseTransform<Derived>::VisitReductionClause(
       if (OrigRecipes.RecipeDecl)
         InitRecipe = OrigRecipes.RecipeDecl;
        else
-         InitRecipe =
-             Self.getSema()
-                 .OpenACC()
-                 .CreateInitRecipe(OpenACCClauseKind::Reduction, Res.get())
-                 .first;
+         InitRecipe = Self.getSema()
+                          .OpenACC()
+                          .CreateInitRecipe(OpenACCClauseKind::Reduction,
+                                            C.getReductionOp(), Res.get())
+                          .first;
 
       Recipes.push_back({InitRecipe});
     }
diff --git 
a/clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp 
b/clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp
index a3f62b4af3c27..7469c7249caab 100644
--- a/clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp
+++ b/clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp
@@ -9,9 +9,45 @@ struct DefaultOperators {
 
 // CHECK: acc.reduction.recipe @reduction_lor__ZTSA5_16DefaultOperators : 
!cir.ptr<!cir.array<!rec_DefaultOperators x 5>> reduction_operator <lor> init {
 // CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_DefaultOperators x 
5>>{{.*}})
-// CHECK-NEXT: cir.alloca !cir.array<!rec_DefaultOperators x 5>, 
!cir.ptr<!cir.array<!rec_DefaultOperators x 5>>, ["openacc.reduction.init"]
-// TODO OpenACC: Expecting an initialization to... SOME value here.
+// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_DefaultOperators x 
5>, !cir.ptr<!cir.array<!rec_DefaultOperators x 5>>, ["openacc.reduction.init", 
init]
+// CHECK-NEXT: %[[TEMP_ITR:.*]] = cir.alloca !cir.ptr<!rec_DefaultOperators>, 
!cir.ptr<!cir.ptr<!rec_DefaultOperators>>, ["arrayinit.temp"]
+// CHECK-NEXT: %[[DECAY:.*]] = cir.cast(array_to_ptrdecay, %[[ALLOCA]] : 
!cir.ptr<!cir.array<!rec_DefaultOperators x 5>>), 
!cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: %[[GET_I:.*]] = cir.get_member %[[DECAY]][0] {name = "i"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!s32i>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_I]] : !s32i, !cir.ptr<!s32i>
+// CHECK-NEXT: %[[GET_F:.*]] = cir.get_member %[[DECAY]][1] {name = "f"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.float>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.float
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_F]] : !cir.float, 
!cir.ptr<!cir.float>
+// CHECK-NEXT: %[[GET_D:.*]] = cir.get_member %[[DECAY]][2] {name = "d"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.double>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.double
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_D]] : !cir.double, 
!cir.ptr<!cir.double>
+// CHECK-NEXT: %[[FIRST_IDX:.*]] = cir.const #cir.int<1> : !s64i
+// CHECK-NEXT: %[[ITEM_ONE:.*]] = cir.ptr_stride(%[[DECAY]] : 
!cir.ptr<!rec_DefaultOperators>, %[[FIRST_IDX]] : !s64i), 
!cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: cir.store {{.*}} %[[ITEM_ONE]], %[[TEMP_ITR]] : 
!cir.ptr<!rec_DefaultOperators>, !cir.ptr<!cir.ptr<!rec_DefaultOperators>>
+// CHECK-NEXT: %[[LAST_IDX:.*]] = cir.const #cir.int<5> : !s64i
+// CHECK-NEXT: %[[END_ITR:.*]] = cir.ptr_stride(%[[DECAY]] : 
!cir.ptr<!rec_DefaultOperators>, %[[LAST_IDX]] : !s64i), 
!cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: cir.do {
+// CHECK-NEXT: %[[TEMP_LOAD:.*]] = cir.load {{.*}} %[[TEMP_ITR]] : 
!cir.ptr<!cir.ptr<!rec_DefaultOperators>>, !cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: %[[GET_I:.*]] = cir.get_member %[[TEMP_LOAD]][0] {name = "i"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!s32i>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_I]] : !s32i, !cir.ptr<!s32i>
+// CHECK-NEXT: %[[GET_F:.*]] = cir.get_member %[[TEMP_LOAD]][1] {name = "f"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.float>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.float
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_F]] : !cir.float, 
!cir.ptr<!cir.float>
+// CHECK-NEXT: %[[GET_D:.*]] = cir.get_member %[[TEMP_LOAD]][2] {name = "d"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.double>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.double
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_D]] : !cir.double, 
!cir.ptr<!cir.double>
+// CHECK-NEXT: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i
+// CHECK-NEXT: %[[NEXT_ITEM:.*]] = cir.ptr_stride(%[[TEMP_LOAD]] : 
!cir.ptr<!rec_DefaultOperators>, %[[ONE]] : !s64i), 
!cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: cir.store {{.*}} %[[NEXT_ITEM]], %[[TEMP_ITR]] : 
!cir.ptr<!rec_DefaultOperators>, !cir.ptr<!cir.ptr<!rec_DefaultOperators>>
+// CHECK-NEXT: cir.yield
+// CHECK-NEXT: } while {
+// CHECK-NEXT: %[[TEMP_LOAD:.*]] = cir.load {{.*}} %[[TEMP_ITR]] : 
!cir.ptr<!cir.ptr<!rec_DefaultOperators>>, !cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(ne, %[[TEMP_LOAD]], %[[END_ITR]]) : 
!cir.ptr<!rec_DefaultOperators>, !cir.bool
+// CHECK-NEXT: cir.condition(%[[CMP]]) 
+// CHECK-NEXT: }
 // CHECK-NEXT: acc.yield
+//
 // CHECK-NEXT: } combiner {
 // CHECK-NEXT: ^bb0(%[[LHSARG:.*]]: !cir.ptr<!cir.array<!rec_DefaultOperators 
x 5>> {{.*}}, %[[RHSARG:.*]]: !cir.ptr<!cir.array<!rec_DefaultOperators x 5>> 
{{.*}})
 // TODO OpenACC: Expecting combination operation here
@@ -31,9 +67,45 @@ struct DefaultOperators {
 
 // CHECK-NEXT: acc.reduction.recipe @reduction_xor__ZTSA5_16DefaultOperators : 
!cir.ptr<!cir.array<!rec_DefaultOperators x 5>> reduction_operator <xor> init {
 // CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_DefaultOperators x 
5>>{{.*}})
-// CHECK-NEXT: cir.alloca !cir.array<!rec_DefaultOperators x 5>, 
!cir.ptr<!cir.array<!rec_DefaultOperators x 5>>, ["openacc.reduction.init"]
-// TODO OpenACC: Expecting an initialization to... SOME value here.
+// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_DefaultOperators x 
5>, !cir.ptr<!cir.array<!rec_DefaultOperators x 5>>, ["openacc.reduction.init", 
init]
+// CHECK-NEXT: %[[TEMP_ITR:.*]] = cir.alloca !cir.ptr<!rec_DefaultOperators>, 
!cir.ptr<!cir.ptr<!rec_DefaultOperators>>, ["arrayinit.temp"]
+// CHECK-NEXT: %[[DECAY:.*]] = cir.cast(array_to_ptrdecay, %[[ALLOCA]] : 
!cir.ptr<!cir.array<!rec_DefaultOperators x 5>>), 
!cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: %[[GET_I:.*]] = cir.get_member %[[DECAY]][0] {name = "i"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!s32i>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_I]] : !s32i, !cir.ptr<!s32i>
+// CHECK-NEXT: %[[GET_F:.*]] = cir.get_member %[[DECAY]][1] {name = "f"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.float>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.float
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_F]] : !cir.float, 
!cir.ptr<!cir.float>
+// CHECK-NEXT: %[[GET_D:.*]] = cir.get_member %[[DECAY]][2] {name = "d"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.double>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.double
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_D]] : !cir.double, 
!cir.ptr<!cir.double>
+// CHECK-NEXT: %[[FIRST_IDX:.*]] = cir.const #cir.int<1> : !s64i
+// CHECK-NEXT: %[[ITEM_ONE:.*]] = cir.ptr_stride(%[[DECAY]] : 
!cir.ptr<!rec_DefaultOperators>, %[[FIRST_IDX]] : !s64i), 
!cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: cir.store {{.*}} %[[ITEM_ONE]], %[[TEMP_ITR]] : 
!cir.ptr<!rec_DefaultOperators>, !cir.ptr<!cir.ptr<!rec_DefaultOperators>>
+// CHECK-NEXT: %[[LAST_IDX:.*]] = cir.const #cir.int<5> : !s64i
+// CHECK-NEXT: %[[END_ITR:.*]] = cir.ptr_stride(%[[DECAY]] : 
!cir.ptr<!rec_DefaultOperators>, %[[LAST_IDX]] : !s64i), 
!cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: cir.do {
+// CHECK-NEXT: %[[TEMP_LOAD:.*]] = cir.load {{.*}} %[[TEMP_ITR]] : 
!cir.ptr<!cir.ptr<!rec_DefaultOperators>>, !cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: %[[GET_I:.*]] = cir.get_member %[[TEMP_LOAD]][0] {name = "i"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!s32i>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_I]] : !s32i, !cir.ptr<!s32i>
+// CHECK-NEXT: %[[GET_F:.*]] = cir.get_member %[[TEMP_LOAD]][1] {name = "f"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.float>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.float
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_F]] : !cir.float, 
!cir.ptr<!cir.float>
+// CHECK-NEXT: %[[GET_D:.*]] = cir.get_member %[[TEMP_LOAD]][2] {name = "d"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.double>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.double
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_D]] : !cir.double, 
!cir.ptr<!cir.double>
+// CHECK-NEXT: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i
+// CHECK-NEXT: %[[NEXT_ITEM:.*]] = cir.ptr_stride(%[[TEMP_LOAD]] : 
!cir.ptr<!rec_DefaultOperators>, %[[ONE]] : !s64i), 
!cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: cir.store {{.*}} %[[NEXT_ITEM]], %[[TEMP_ITR]] : 
!cir.ptr<!rec_DefaultOperators>, !cir.ptr<!cir.ptr<!rec_DefaultOperators>>
+// CHECK-NEXT: cir.yield
+// CHECK-NEXT: } while {
+// CHECK-NEXT: %[[TEMP_LOAD:.*]] = cir.load {{.*}} %[[TEMP_ITR]] : 
!cir.ptr<!cir.ptr<!rec_DefaultOperators>>, !cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(ne, %[[TEMP_LOAD]], %[[END_ITR]]) : 
!cir.ptr<!rec_DefaultOperators>, !cir.bool
+// CHECK-NEXT: cir.condition(%[[CMP]]) 
+// CHECK-NEXT: }
 // CHECK-NEXT: acc.yield
+//
 // CHECK-NEXT: } combiner {
 // CHECK-NEXT: ^bb0(%[[LHSARG:.*]]: !cir.ptr<!cir.array<!rec_DefaultOperators 
x 5>> {{.*}}, %[[RHSARG:.*]]: !cir.ptr<!cir.array<!rec_DefaultOperators x 5>> 
{{.*}})
 // TODO OpenACC: Expecting combination operation here
@@ -42,9 +114,45 @@ struct DefaultOperators {
 
 // CHECK-NEXT: acc.reduction.recipe @reduction_ior__ZTSA5_16DefaultOperators : 
!cir.ptr<!cir.array<!rec_DefaultOperators x 5>> reduction_operator <ior> init {
 // CHECK-NEXT: ^bb0(%[[ARG:.*]]: !cir.ptr<!cir.array<!rec_DefaultOperators x 
5>>{{.*}})
-// CHECK-NEXT: cir.alloca !cir.array<!rec_DefaultOperators x 5>, 
!cir.ptr<!cir.array<!rec_DefaultOperators x 5>>, ["openacc.reduction.init"]
-// TODO OpenACC: Expecting an initialization to... SOME value here.
+// CHECK-NEXT: %[[ALLOCA:.*]] = cir.alloca !cir.array<!rec_DefaultOperators x 
5>, !cir.ptr<!cir.array<!rec_DefaultOperators x 5>>, ["openacc.reduction.init", 
init]
+// CHECK-NEXT: %[[TEMP_ITR:.*]] = cir.alloca !cir.ptr<!rec_DefaultOperators>, 
!cir.ptr<!cir.ptr<!rec_DefaultOperators>>, ["arrayinit.temp"]
+// CHECK-NEXT: %[[DECAY:.*]] = cir.cast(array_to_ptrdecay, %[[ALLOCA]] : 
!cir.ptr<!cir.array<!rec_DefaultOperators x 5>>), 
!cir.ptr<!rec_DefaultOperators>
+// CHECK-NEXT: %[[GET_I:.*]] = cir.get_member %[[DECAY]][0] {name = "i"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!s32i>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_I]] : !s32i, !cir.ptr<!s32i>
+// CHECK-NEXT: %[[GET_F:.*]] = cir.get_member %[[DECAY]][1] {name = "f"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.float>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.float
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_F]] : !cir.float, 
!cir.ptr<!cir.float>
+// CHECK-NEXT: %[[GET_D:.*]] = cir.get_member %[[DECAY]][2] {name = "d"} : 
!cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.double>
+// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.fp<0{{.*}}> : !cir.double
+// CHECK-NEXT: cir.store {{.*}} %[[ZERO]], %[[GET_D]] : !cir.d...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/155924
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to