Skip to content

Commit 91c2607

Browse files
[flang][acc] Avoid implicitly privatizing IVs already privatized (llvm#136181)
When generating `acc.loop`, the IV was always implicitly privatized. However, if the user explicitly privatized it, the IR generated wasn't quite right. For example: ``` !$acc loop private(i) do i = 1, n a(i) = b(i) end do ``` The IR generated looked like: ``` %65 = acc.private varPtr(%19#0 : !fir.ref<i32>) -> !fir.ref<i32> {implicit = true, name = "i"} %66:2 = hlfir.declare %65 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) %67 = acc.private varPtr(%66#0 : !fir.ref<i32>) -> !fir.ref<i32> {name = "i"} acc.loop private(@privatization_ref_i32 -> %65 : !fir.ref<i32>, @privatization_ref_i32 -> %67 : !fir.ref<i32>) control(%arg0 : i32) = (%c1_i32_46 : i32) to (%c10_i32_47 : i32) step (%c1_i32_48 : i32) { fir.store %arg0 to %66#0 : !fir.ref<i32> ``` In order to fix this, we first process all of the clauses. Then when attempting to generate implicit private IV, we look for an already existing data clause operation. The result is the following IR: ``` %65 = acc.private varPtr(%19#0 : !fir.ref<i32>) -> !fir.ref<i32> {name = "i"} %66:2 = hlfir.declare %65 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) acc.loop private(@privatization_ref_i32 -> %65 : !fir.ref<i32>) control(%arg0 : i32) = (%c1_i32_46 : i32) to (%c10_i32_47 : i32) step (%c1_i32_48 : i32) { fir.store %arg0 to %66#0 : !fir.ref<i32> ```
1 parent 91f9f0f commit 91c2607

File tree

7 files changed

+151
-131
lines changed

7 files changed

+151
-131
lines changed

flang/lib/Lower/OpenACC.cpp

Lines changed: 111 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,27 +1804,38 @@ static void privatizeIv(Fortran::lower::AbstractConverter &converter,
18041804
builder.restoreInsertionPoint(insPt);
18051805
}
18061806

1807-
std::string recipeName =
1808-
fir::getTypeAsString(ivValue.getType(), converter.getKindMap(),
1809-
Fortran::lower::privatizationRecipePrefix);
1810-
auto recipe = Fortran::lower::createOrGetPrivateRecipe(
1811-
builder, recipeName, loc, ivValue.getType());
1807+
mlir::Operation *privateOp = nullptr;
1808+
for (auto privateVal : privateOperands) {
1809+
if (mlir::acc::getVar(privateVal.getDefiningOp()) == ivValue) {
1810+
privateOp = privateVal.getDefiningOp();
1811+
break;
1812+
}
1813+
}
18121814

1813-
std::stringstream asFortran;
1814-
asFortran << Fortran::lower::mangle::demangleName(toStringRef(sym.name()));
1815-
auto op = createDataEntryOp<mlir::acc::PrivateOp>(
1816-
builder, loc, ivValue, asFortran, {}, true, /*implicit=*/true,
1817-
mlir::acc::DataClause::acc_private, ivValue.getType(),
1818-
/*async=*/{}, /*asyncDeviceTypes=*/{}, /*asyncOnlyDeviceTypes=*/{});
1815+
if (privateOp == nullptr) {
1816+
std::string recipeName =
1817+
fir::getTypeAsString(ivValue.getType(), converter.getKindMap(),
1818+
Fortran::lower::privatizationRecipePrefix);
1819+
auto recipe = Fortran::lower::createOrGetPrivateRecipe(
1820+
builder, recipeName, loc, ivValue.getType());
1821+
1822+
std::stringstream asFortran;
1823+
asFortran << Fortran::lower::mangle::demangleName(toStringRef(sym.name()));
1824+
auto op = createDataEntryOp<mlir::acc::PrivateOp>(
1825+
builder, loc, ivValue, asFortran, {}, true, /*implicit=*/true,
1826+
mlir::acc::DataClause::acc_private, ivValue.getType(),
1827+
/*async=*/{}, /*asyncDeviceTypes=*/{}, /*asyncOnlyDeviceTypes=*/{});
1828+
privateOp = op.getOperation();
18191829

1820-
privateOperands.push_back(op.getAccVar());
1821-
privatizations.push_back(mlir::SymbolRefAttr::get(builder.getContext(),
1822-
recipe.getSymName().str()));
1830+
privateOperands.push_back(op.getAccVar());
1831+
privatizations.push_back(mlir::SymbolRefAttr::get(
1832+
builder.getContext(), recipe.getSymName().str()));
1833+
}
18231834

18241835
// Map the new private iv to its symbol for the scope of the loop. bindSymbol
18251836
// might create a hlfir.declare op, if so, we map its result in order to
18261837
// use the sym value in the scope.
1827-
converter.bindSymbol(sym, op.getAccVar());
1838+
converter.bindSymbol(sym, mlir::acc::getAccVar(privateOp));
18281839
auto privateValue = converter.getSymbolAddress(sym);
18291840
if (auto declareOp =
18301841
mlir::dyn_cast<hlfir::DeclareOp>(privateValue.getDefiningOp()))
@@ -1863,92 +1874,6 @@ static mlir::acc::LoopOp createLoopOp(
18631874
crtDeviceTypes.push_back(mlir::acc::DeviceTypeAttr::get(
18641875
builder.getContext(), mlir::acc::DeviceType::None));
18651876

1866-
llvm::SmallVector<mlir::Type> ivTypes;
1867-
llvm::SmallVector<mlir::Location> ivLocs;
1868-
llvm::SmallVector<bool> inclusiveBounds;
1869-
1870-
llvm::SmallVector<mlir::Location> locs;
1871-
locs.push_back(currentLocation); // Location of the directive
1872-
Fortran::lower::pft::Evaluation *crtEval = &eval.getFirstNestedEvaluation();
1873-
bool isDoConcurrent = outerDoConstruct.IsDoConcurrent();
1874-
if (isDoConcurrent) {
1875-
locs.push_back(converter.genLocation(
1876-
Fortran::parser::FindSourceLocation(outerDoConstruct)));
1877-
const Fortran::parser::LoopControl *loopControl =
1878-
&*outerDoConstruct.GetLoopControl();
1879-
const auto &concurrent =
1880-
std::get<Fortran::parser::LoopControl::Concurrent>(loopControl->u);
1881-
if (!std::get<std::list<Fortran::parser::LocalitySpec>>(concurrent.t)
1882-
.empty())
1883-
TODO(currentLocation, "DO CONCURRENT with locality spec");
1884-
1885-
const auto &concurrentHeader =
1886-
std::get<Fortran::parser::ConcurrentHeader>(concurrent.t);
1887-
const auto &controls =
1888-
std::get<std::list<Fortran::parser::ConcurrentControl>>(
1889-
concurrentHeader.t);
1890-
for (const auto &control : controls) {
1891-
lowerbounds.push_back(fir::getBase(converter.genExprValue(
1892-
*Fortran::semantics::GetExpr(std::get<1>(control.t)), stmtCtx)));
1893-
upperbounds.push_back(fir::getBase(converter.genExprValue(
1894-
*Fortran::semantics::GetExpr(std::get<2>(control.t)), stmtCtx)));
1895-
if (const auto &expr =
1896-
std::get<std::optional<Fortran::parser::ScalarIntExpr>>(
1897-
control.t))
1898-
steps.push_back(fir::getBase(converter.genExprValue(
1899-
*Fortran::semantics::GetExpr(*expr), stmtCtx)));
1900-
else // If `step` is not present, assume it is `1`.
1901-
steps.push_back(builder.createIntegerConstant(
1902-
currentLocation, upperbounds[upperbounds.size() - 1].getType(), 1));
1903-
1904-
const auto &name = std::get<Fortran::parser::Name>(control.t);
1905-
privatizeIv(converter, *name.symbol, currentLocation, ivTypes, ivLocs,
1906-
privateOperands, ivPrivate, privatizations, isDoConcurrent);
1907-
1908-
inclusiveBounds.push_back(true);
1909-
}
1910-
} else {
1911-
int64_t collapseValue = Fortran::lower::getCollapseValue(accClauseList);
1912-
for (unsigned i = 0; i < collapseValue; ++i) {
1913-
const Fortran::parser::LoopControl *loopControl;
1914-
if (i == 0) {
1915-
loopControl = &*outerDoConstruct.GetLoopControl();
1916-
locs.push_back(converter.genLocation(
1917-
Fortran::parser::FindSourceLocation(outerDoConstruct)));
1918-
} else {
1919-
auto *doCons = crtEval->getIf<Fortran::parser::DoConstruct>();
1920-
assert(doCons && "expect do construct");
1921-
loopControl = &*doCons->GetLoopControl();
1922-
locs.push_back(converter.genLocation(
1923-
Fortran::parser::FindSourceLocation(*doCons)));
1924-
}
1925-
1926-
const Fortran::parser::LoopControl::Bounds *bounds =
1927-
std::get_if<Fortran::parser::LoopControl::Bounds>(&loopControl->u);
1928-
assert(bounds && "Expected bounds on the loop construct");
1929-
lowerbounds.push_back(fir::getBase(converter.genExprValue(
1930-
*Fortran::semantics::GetExpr(bounds->lower), stmtCtx)));
1931-
upperbounds.push_back(fir::getBase(converter.genExprValue(
1932-
*Fortran::semantics::GetExpr(bounds->upper), stmtCtx)));
1933-
if (bounds->step)
1934-
steps.push_back(fir::getBase(converter.genExprValue(
1935-
*Fortran::semantics::GetExpr(bounds->step), stmtCtx)));
1936-
else // If `step` is not present, assume it is `1`.
1937-
steps.push_back(builder.createIntegerConstant(
1938-
currentLocation, upperbounds[upperbounds.size() - 1].getType(), 1));
1939-
1940-
Fortran::semantics::Symbol &ivSym =
1941-
bounds->name.thing.symbol->GetUltimate();
1942-
privatizeIv(converter, ivSym, currentLocation, ivTypes, ivLocs,
1943-
privateOperands, ivPrivate, privatizations);
1944-
1945-
inclusiveBounds.push_back(true);
1946-
1947-
if (i < collapseValue - 1)
1948-
crtEval = &*std::next(crtEval->getNestedEvaluations().begin());
1949-
}
1950-
}
1951-
19521877
for (const Fortran::parser::AccClause &clause : accClauseList.v) {
19531878
mlir::Location clauseLocation = converter.genLocation(clause.source);
19541879
if (const auto *gangClause =
@@ -2101,6 +2026,91 @@ static mlir::acc::LoopOp createLoopOp(
21012026
}
21022027
}
21032028

2029+
llvm::SmallVector<mlir::Type> ivTypes;
2030+
llvm::SmallVector<mlir::Location> ivLocs;
2031+
llvm::SmallVector<bool> inclusiveBounds;
2032+
llvm::SmallVector<mlir::Location> locs;
2033+
locs.push_back(currentLocation); // Location of the directive
2034+
Fortran::lower::pft::Evaluation *crtEval = &eval.getFirstNestedEvaluation();
2035+
bool isDoConcurrent = outerDoConstruct.IsDoConcurrent();
2036+
if (isDoConcurrent) {
2037+
locs.push_back(converter.genLocation(
2038+
Fortran::parser::FindSourceLocation(outerDoConstruct)));
2039+
const Fortran::parser::LoopControl *loopControl =
2040+
&*outerDoConstruct.GetLoopControl();
2041+
const auto &concurrent =
2042+
std::get<Fortran::parser::LoopControl::Concurrent>(loopControl->u);
2043+
if (!std::get<std::list<Fortran::parser::LocalitySpec>>(concurrent.t)
2044+
.empty())
2045+
TODO(currentLocation, "DO CONCURRENT with locality spec");
2046+
2047+
const auto &concurrentHeader =
2048+
std::get<Fortran::parser::ConcurrentHeader>(concurrent.t);
2049+
const auto &controls =
2050+
std::get<std::list<Fortran::parser::ConcurrentControl>>(
2051+
concurrentHeader.t);
2052+
for (const auto &control : controls) {
2053+
lowerbounds.push_back(fir::getBase(converter.genExprValue(
2054+
*Fortran::semantics::GetExpr(std::get<1>(control.t)), stmtCtx)));
2055+
upperbounds.push_back(fir::getBase(converter.genExprValue(
2056+
*Fortran::semantics::GetExpr(std::get<2>(control.t)), stmtCtx)));
2057+
if (const auto &expr =
2058+
std::get<std::optional<Fortran::parser::ScalarIntExpr>>(
2059+
control.t))
2060+
steps.push_back(fir::getBase(converter.genExprValue(
2061+
*Fortran::semantics::GetExpr(*expr), stmtCtx)));
2062+
else // If `step` is not present, assume it is `1`.
2063+
steps.push_back(builder.createIntegerConstant(
2064+
currentLocation, upperbounds[upperbounds.size() - 1].getType(), 1));
2065+
2066+
const auto &name = std::get<Fortran::parser::Name>(control.t);
2067+
privatizeIv(converter, *name.symbol, currentLocation, ivTypes, ivLocs,
2068+
privateOperands, ivPrivate, privatizations, isDoConcurrent);
2069+
2070+
inclusiveBounds.push_back(true);
2071+
}
2072+
} else {
2073+
int64_t collapseValue = Fortran::lower::getCollapseValue(accClauseList);
2074+
for (unsigned i = 0; i < collapseValue; ++i) {
2075+
const Fortran::parser::LoopControl *loopControl;
2076+
if (i == 0) {
2077+
loopControl = &*outerDoConstruct.GetLoopControl();
2078+
locs.push_back(converter.genLocation(
2079+
Fortran::parser::FindSourceLocation(outerDoConstruct)));
2080+
} else {
2081+
auto *doCons = crtEval->getIf<Fortran::parser::DoConstruct>();
2082+
assert(doCons && "expect do construct");
2083+
loopControl = &*doCons->GetLoopControl();
2084+
locs.push_back(converter.genLocation(
2085+
Fortran::parser::FindSourceLocation(*doCons)));
2086+
}
2087+
2088+
const Fortran::parser::LoopControl::Bounds *bounds =
2089+
std::get_if<Fortran::parser::LoopControl::Bounds>(&loopControl->u);
2090+
assert(bounds && "Expected bounds on the loop construct");
2091+
lowerbounds.push_back(fir::getBase(converter.genExprValue(
2092+
*Fortran::semantics::GetExpr(bounds->lower), stmtCtx)));
2093+
upperbounds.push_back(fir::getBase(converter.genExprValue(
2094+
*Fortran::semantics::GetExpr(bounds->upper), stmtCtx)));
2095+
if (bounds->step)
2096+
steps.push_back(fir::getBase(converter.genExprValue(
2097+
*Fortran::semantics::GetExpr(bounds->step), stmtCtx)));
2098+
else // If `step` is not present, assume it is `1`.
2099+
steps.push_back(builder.createIntegerConstant(
2100+
currentLocation, upperbounds[upperbounds.size() - 1].getType(), 1));
2101+
2102+
Fortran::semantics::Symbol &ivSym =
2103+
bounds->name.thing.symbol->GetUltimate();
2104+
privatizeIv(converter, ivSym, currentLocation, ivTypes, ivLocs,
2105+
privateOperands, ivPrivate, privatizations);
2106+
2107+
inclusiveBounds.push_back(true);
2108+
2109+
if (i < collapseValue - 1)
2110+
crtEval = &*std::next(crtEval->getNestedEvaluations().begin());
2111+
}
2112+
}
2113+
21042114
// Prepare the operand segment size attribute and the operands value range.
21052115
llvm::SmallVector<mlir::Value> operands;
21062116
llvm::SmallVector<int32_t> operandSegments;

flang/test/Lower/OpenACC/acc-kernels-loop.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ subroutine acc_kernels_loop
495495

496496
! CHECK: acc.kernels {{.*}} {
497497
! CHECK: [[GANGNUM1:%.*]] = arith.constant 8 : i32
498-
! CHECK-NEXT: acc.loop {{.*}} gang({num=[[GANGNUM1]] : i32}) {{.*}} {
498+
! CHECK: acc.loop {{.*}} gang({num=[[GANGNUM1]] : i32}) {{.*}} {
499499
! CHECK: acc.yield
500500
! CHECK-NEXT: }{{$}}
501501
! CHECK: acc.terminator
@@ -508,7 +508,7 @@ subroutine acc_kernels_loop
508508

509509
! CHECK: acc.kernels {{.*}} {
510510
! CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
511-
! CHECK-NEXT: acc.loop {{.*}} gang({num=[[GANGNUM2]] : i32}) {{.*}} {
511+
! CHECK: acc.loop {{.*}} gang({num=[[GANGNUM2]] : i32}) {{.*}} {
512512
! CHECK: acc.yield
513513
! CHECK-NEXT: }{{$}}
514514
! CHECK: acc.terminator

flang/test/Lower/OpenACC/acc-loop.f90

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ program acc_loop
7373
END DO
7474

7575
! CHECK: [[GANGNUM1:%.*]] = arith.constant 8 : i32
76-
! CHECK-NEXT: acc.loop gang({num=[[GANGNUM1]] : i32}) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
76+
! CHECK: acc.loop gang({num=[[GANGNUM1]] : i32}) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
7777
! CHECK: acc.yield
7878
! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
7979

@@ -83,7 +83,7 @@ program acc_loop
8383
END DO
8484

8585
! CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
86-
! CHECK-NEXT: acc.loop gang({num=[[GANGNUM2]] : i32}) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
86+
! CHECK: acc.loop gang({num=[[GANGNUM2]] : i32}) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
8787
! CHECK: acc.yield
8888
! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
8989

@@ -145,29 +145,39 @@ program acc_loop
145145
! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
146146

147147
!$acc loop private(c)
148+
DO i = 1, n
149+
c(:,i) = d(:,i)
150+
END DO
151+
152+
! CHECK: acc.loop private(@privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, @privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
153+
! CHECK: acc.yield
154+
! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
155+
156+
! When the induction variable is explicitly private - only a single private entry should be created.
157+
!$acc loop private(i)
148158
DO i = 1, n
149159
a(i) = b(i)
150160
END DO
151161

152-
! CHECK: acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
162+
! CHECK: acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
153163
! CHECK: acc.yield
154164
! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
155165

156166
!$acc loop private(c, d)
157167
DO i = 1, n
158-
a(i) = b(i)
168+
c(:,i) = d(:,i)
159169
END DO
160170

161-
! CHECK: acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
171+
! CHECK: acc.loop private(@privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, @privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
162172
! CHECK: acc.yield
163173
! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
164174

165175
!$acc loop private(c) private(d)
166176
DO i = 1, n
167-
a(i) = b(i)
177+
c(:,i) = d(:,i)
168178
END DO
169179

170-
! CHECK: acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
180+
! CHECK: acc.loop private(@privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, @privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
171181
! CHECK: acc.yield
172182
! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
173183

flang/test/Lower/OpenACC/acc-parallel-loop.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ subroutine acc_parallel_loop
448448
! CHECK: %[[ACC_PRIVATE_B:.*]] = acc.firstprivate varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
449449
! CHECK: acc.parallel {{.*}} firstprivate(@firstprivatization_ref_10xf32 -> %[[ACC_PRIVATE_B]] : !fir.ref<!fir.array<10xf32>>) {
450450
! CHECK: %[[ACC_PRIVATE_A:.*]] = acc.private varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
451-
! CHECK: acc.loop {{.*}} private({{.*}}@privatization_ref_10xf32 -> %[[ACC_PRIVATE_A]] : !fir.ref<!fir.array<10xf32>>)
451+
! CHECK: acc.loop {{.*}} private({{.*}}@privatization_ref_10xf32 -> %[[ACC_PRIVATE_A]] : !fir.ref<!fir.array<10xf32>>{{.*}})
452452
! CHECK-NOT: fir.do_loop
453453
! CHECK: acc.yield
454454
! CHECK-NEXT: }{{$}}
@@ -510,7 +510,7 @@ subroutine acc_parallel_loop
510510

511511
! CHECK: acc.parallel {{.*}} {
512512
! CHECK: [[GANGNUM1:%.*]] = arith.constant 8 : i32
513-
! CHECK-NEXT: acc.loop {{.*}} gang({num=[[GANGNUM1]] : i32})
513+
! CHECK: acc.loop {{.*}} gang({num=[[GANGNUM1]] : i32})
514514
! CHECK: acc.yield
515515
! CHECK-NEXT: }{{$}}
516516
! CHECK: acc.yield
@@ -523,7 +523,7 @@ subroutine acc_parallel_loop
523523

524524
! CHECK: acc.parallel {{.*}} {
525525
! CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
526-
! CHECK-NEXT: acc.loop {{.*}} gang({num=[[GANGNUM2]] : i32})
526+
! CHECK: acc.loop {{.*}} gang({num=[[GANGNUM2]] : i32})
527527
! CHECK: acc.yield
528528
! CHECK-NEXT: }{{$}}
529529
! CHECK: acc.yield

0 commit comments

Comments
 (0)