Skip to content

Commit 27f777e

Browse files
authored
[Flang][OpenMP] Skip DSA for canonical loops (#150593)
OpenMP loop transformations to not have data-sharing attributes and do not explicitly privatize the loop variable. The DataSharingProcessor was still used in #144785 because `createAndSetPrivatizedLoopVar` expected it. We skip that function and directly write to the loop variable. If the loop variable is implicitly or explicitly privatized, it will be due to surrounding OpenMP constructs such as `parallel`.
1 parent d3b2bda commit 27f777e

File tree

4 files changed

+173
-100
lines changed

4 files changed

+173
-100
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -697,20 +697,16 @@ static void threadPrivatizeVars(lower::AbstractConverter &converter,
697697
}
698698
}
699699

700-
static mlir::Operation *
701-
createAndSetPrivatizedLoopVar(lower::AbstractConverter &converter,
702-
mlir::Location loc, mlir::Value indexVal,
703-
const semantics::Symbol *sym) {
700+
static mlir::Operation *setLoopVar(lower::AbstractConverter &converter,
701+
mlir::Location loc, mlir::Value indexVal,
702+
const semantics::Symbol *sym) {
704703
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
704+
705705
mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint();
706706
firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock());
707-
708707
mlir::Type tempTy = converter.genType(*sym);
709-
710-
assert(converter.isPresentShallowLookup(*sym) &&
711-
"Expected symbol to be in symbol table.");
712-
713708
firOpBuilder.restoreInsertionPoint(insPt);
709+
714710
mlir::Value cvtVal = firOpBuilder.createConvert(loc, tempTy, indexVal);
715711
hlfir::Entity lhs{converter.getSymbolAddress(*sym)};
716712

@@ -721,6 +717,15 @@ createAndSetPrivatizedLoopVar(lower::AbstractConverter &converter,
721717
return storeOp;
722718
}
723719

720+
static mlir::Operation *
721+
createAndSetPrivatizedLoopVar(lower::AbstractConverter &converter,
722+
mlir::Location loc, mlir::Value indexVal,
723+
const semantics::Symbol *sym) {
724+
assert(converter.isPresentShallowLookup(*sym) &&
725+
"Expected symbol to be in symbol table.");
726+
return setLoopVar(converter, loc, indexVal, sym);
727+
}
728+
724729
// This helper function implements the functionality of "promoting" non-CPTR
725730
// arguments of use_device_ptr to use_device_addr arguments (automagic
726731
// conversion of use_device_ptr -> use_device_addr in these cases). The way we
@@ -1123,6 +1128,11 @@ struct OpWithBodyGenInfo {
11231128
return *this;
11241129
}
11251130

1131+
OpWithBodyGenInfo &setPrivatize(bool value) {
1132+
privatize = value;
1133+
return *this;
1134+
}
1135+
11261136
/// [inout] converter to use for the clauses.
11271137
lower::AbstractConverter &converter;
11281138
/// [in] Symbol table
@@ -1149,6 +1159,8 @@ struct OpWithBodyGenInfo {
11491159
/// [in] if set to `true`, skip generating nested evaluations and dispatching
11501160
/// any further leaf constructs.
11511161
bool genSkeletonOnly = false;
1162+
/// [in] enables handling of privatized variable unless set to `false`.
1163+
bool privatize = true;
11521164
};
11531165

11541166
/// Create the body (block) for an OpenMP Operation.
@@ -1209,7 +1221,7 @@ static void createBodyOfOp(mlir::Operation &op, const OpWithBodyGenInfo &info,
12091221
// code will use the right symbols.
12101222
bool isLoop = llvm::omp::getDirectiveAssociation(info.dir) ==
12111223
llvm::omp::Association::Loop;
1212-
bool privatize = info.clauses;
1224+
bool privatize = info.clauses && info.privatize;
12131225

12141226
firOpBuilder.setInsertionPoint(marker);
12151227
std::optional<DataSharingProcessor> tempDsp;
@@ -2083,7 +2095,7 @@ genCanonicalLoopOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
20832095
const ConstructQueue &queue,
20842096
ConstructQueue::const_iterator item,
20852097
llvm::ArrayRef<const semantics::Symbol *> ivs,
2086-
llvm::omp::Directive directive, DataSharingProcessor &dsp) {
2098+
llvm::omp::Directive directive) {
20872099
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
20882100

20892101
assert(ivs.size() == 1 && "Nested loops not yet implemented");
@@ -2176,10 +2188,8 @@ genCanonicalLoopOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
21762188
mlir::Value userVal =
21772189
firOpBuilder.create<mlir::arith::AddIOp>(loc, loopLBVar, scaled);
21782190

2179-
// The argument is not currently in memory, so make a temporary for the
2180-
// argument, and store it there, then bind that location to the argument.
2181-
mlir::Operation *storeOp =
2182-
createAndSetPrivatizedLoopVar(converter, loc, userVal, iv);
2191+
// Write loop value to loop variable
2192+
mlir::Operation *storeOp = setLoopVar(converter, loc, userVal, iv);
21832193

21842194
firOpBuilder.setInsertionPointAfter(storeOp);
21852195
return {iv};
@@ -2190,7 +2200,7 @@ genCanonicalLoopOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
21902200
OpWithBodyGenInfo(converter, symTable, semaCtx, loc, nestedEval,
21912201
directive)
21922202
.setClauses(&item->clauses)
2193-
.setDataSharingProcessor(&dsp)
2203+
.setPrivatize(false)
21942204
.setGenRegionEntryCb(ivCallback),
21952205
queue, item, tripcount, cli);
21962206

@@ -2216,17 +2226,10 @@ static void genUnrollOp(Fortran::lower::AbstractConverter &converter,
22162226
cp.processTODO<clause::Partial, clause::Full>(
22172227
loc, llvm::omp::Directive::OMPD_unroll);
22182228

2219-
// Even though unroll does not support data-sharing clauses, but this is
2220-
// required to fill the symbol table.
2221-
DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
2222-
/*shouldCollectPreDeterminedSymbols=*/true,
2223-
/*useDelayedPrivatization=*/false, symTable);
2224-
dsp.processStep1();
2225-
22262229
// Emit the associated loop
22272230
auto canonLoop =
22282231
genCanonicalLoopOp(converter, symTable, semaCtx, eval, loc, queue, item,
2229-
iv, llvm::omp::Directive::OMPD_unroll, dsp);
2232+
iv, llvm::omp::Directive::OMPD_unroll);
22302233

22312234
// Apply unrolling to it
22322235
auto cli = canonLoop.getCli();

flang/test/Lower/OpenMP/unroll-heuristic01.f90

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,42 @@ subroutine omp_unroll_heuristic01(lb, ub, inc)
1313
end subroutine omp_unroll_heuristic01
1414

1515

16-
!CHECK-LABEL: func.func @_QPomp_unroll_heuristic01(
17-
!CHECK: %c0_i32 = arith.constant 0 : i32
18-
!CHECK-NEXT: %c1_i32 = arith.constant 1 : i32
19-
!CHECK-NEXT: %13 = arith.cmpi slt, %12, %c0_i32 : i32
20-
!CHECK-NEXT: %14 = arith.subi %c0_i32, %12 : i32
21-
!CHECK-NEXT: %15 = arith.select %13, %14, %12 : i32
22-
!CHECK-NEXT: %16 = arith.select %13, %11, %10 : i32
23-
!CHECK-NEXT: %17 = arith.select %13, %10, %11 : i32
24-
!CHECK-NEXT: %18 = arith.subi %17, %16 overflow<nuw> : i32
25-
!CHECK-NEXT: %19 = arith.divui %18, %15 : i32
26-
!CHECK-NEXT: %20 = arith.addi %19, %c1_i32 overflow<nuw> : i32
27-
!CHECK-NEXT: %21 = arith.cmpi slt, %17, %16 : i32
28-
!CHECK-NEXT: %22 = arith.select %21, %c0_i32, %20 : i32
29-
!CHECK-NEXT: %canonloop_s0 = omp.new_cli
30-
!CHECK-NEXT: omp.canonical_loop(%canonloop_s0) %iv : i32 in range(%22) {
31-
!CHECK-NEXT: %23 = arith.muli %iv, %12 : i32
32-
!CHECK-NEXT: %24 = arith.addi %10, %23 : i32
33-
!CHECK-NEXT: hlfir.assign %24 to %9#0 : i32, !fir.ref<i32>
34-
!CHECK-NEXT: %25 = fir.load %9#0 : !fir.ref<i32>
35-
!CHECK-NEXT: hlfir.assign %25 to %6#0 : i32, !fir.ref<i32>
36-
!CHECK-NEXT: omp.terminator
37-
!CHECK-NEXT: }
38-
!CHECK-NEXT: omp.unroll_heuristic(%canonloop_s0)
39-
!CHECK-NEXT: return
16+
! CHECK-LABEL: func.func @_QPomp_unroll_heuristic01(
17+
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {fir.bindc_name = "lb"},
18+
! CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "ub"},
19+
! CHECK-SAME: %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "inc"}) {
20+
! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope
21+
! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_unroll_heuristic01Ei"}
22+
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFomp_unroll_heuristic01Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
23+
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[ARG2]] dummy_scope %[[VAL_0]] {uniq_name = "_QFomp_unroll_heuristic01Einc"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
24+
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {uniq_name = "_QFomp_unroll_heuristic01Elb"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
25+
! CHECK: %[[VAL_5:.*]] = fir.alloca i32 {bindc_name = "res", uniq_name = "_QFomp_unroll_heuristic01Eres"}
26+
! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] {uniq_name = "_QFomp_unroll_heuristic01Eres"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
27+
! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QFomp_unroll_heuristic01Eub"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
28+
! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32>
29+
! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<i32>
30+
! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
31+
! CHECK: %[[VAL_11:.*]] = arith.constant 0 : i32
32+
! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i32
33+
! CHECK: %[[VAL_13:.*]] = arith.cmpi slt, %[[VAL_10]], %[[VAL_11]] : i32
34+
! CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_11]], %[[VAL_10]] : i32
35+
! CHECK: %[[VAL_15:.*]] = arith.select %[[VAL_13]], %[[VAL_14]], %[[VAL_10]] : i32
36+
! CHECK: %[[VAL_16:.*]] = arith.select %[[VAL_13]], %[[VAL_9]], %[[VAL_8]] : i32
37+
! CHECK: %[[VAL_17:.*]] = arith.select %[[VAL_13]], %[[VAL_8]], %[[VAL_9]] : i32
38+
! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_16]] overflow<nuw> : i32
39+
! CHECK: %[[VAL_19:.*]] = arith.divui %[[VAL_18]], %[[VAL_15]] : i32
40+
! CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_19]], %[[VAL_12]] overflow<nuw> : i32
41+
! CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_17]], %[[VAL_16]] : i32
42+
! CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_21]], %[[VAL_11]], %[[VAL_20]] : i32
43+
! CHECK: %[[VAL_23:.*]] = omp.new_cli
44+
! CHECK: omp.canonical_loop(%[[VAL_23]]) %[[VAL_24:.*]] : i32 in range(%[[VAL_22]]) {
45+
! CHECK: %[[VAL_25:.*]] = arith.muli %[[VAL_24]], %[[VAL_10]] : i32
46+
! CHECK: %[[VAL_26:.*]] = arith.addi %[[VAL_8]], %[[VAL_25]] : i32
47+
! CHECK: hlfir.assign %[[VAL_26]] to %[[VAL_2]]#0 : i32, !fir.ref<i32>
48+
! CHECK: %[[VAL_27:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<i32>
49+
! CHECK: hlfir.assign %[[VAL_27]] to %[[VAL_6]]#0 : i32, !fir.ref<i32>
50+
! CHECK: omp.terminator
51+
! CHECK: }
52+
! CHECK: omp.unroll_heuristic(%[[VAL_23]])
53+
! CHECK: return
54+
! CHECK: }

flang/test/Lower/OpenMP/unroll-heuristic02.f90

Lines changed: 46 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,61 +37,55 @@ end subroutine omp_unroll_heuristic_nested02
3737
!CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QFomp_unroll_heuristic_nested02Eouter_ub"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
3838
!CHECK: %[[VAL_11:.*]] = fir.alloca i32 {bindc_name = "res", uniq_name = "_QFomp_unroll_heuristic_nested02Eres"}
3939
!CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] {uniq_name = "_QFomp_unroll_heuristic_nested02Eres"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
40-
!CHECK: %[[VAL_13:.*]] = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFomp_unroll_heuristic_nested02Ei"}
41-
!CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_13]] {uniq_name = "_QFomp_unroll_heuristic_nested02Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
42-
!CHECK: %[[VAL_15:.*]] = fir.alloca i32 {bindc_name = "j", pinned, uniq_name = "_QFomp_unroll_heuristic_nested02Ej"}
43-
!CHECK: %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_15]] {uniq_name = "_QFomp_unroll_heuristic_nested02Ej"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
44-
!CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i32>
45-
!CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<i32>
46-
!CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32>
47-
!CHECK: %[[VAL_20:.*]] = arith.constant 0 : i32
48-
!CHECK: %[[VAL_21:.*]] = arith.constant 1 : i32
49-
!CHECK: %[[VAL_22:.*]] = arith.cmpi slt, %[[VAL_19]], %[[VAL_20]] : i32
50-
!CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_20]], %[[VAL_19]] : i32
51-
!CHECK: %[[VAL_24:.*]] = arith.select %[[VAL_22]], %[[VAL_23]], %[[VAL_19]] : i32
52-
!CHECK: %[[VAL_25:.*]] = arith.select %[[VAL_22]], %[[VAL_18]], %[[VAL_17]] : i32
53-
!CHECK: %[[VAL_26:.*]] = arith.select %[[VAL_22]], %[[VAL_17]], %[[VAL_18]] : i32
54-
!CHECK: %[[VAL_27:.*]] = arith.subi %[[VAL_26]], %[[VAL_25]] overflow<nuw> : i32
55-
!CHECK: %[[VAL_28:.*]] = arith.divui %[[VAL_27]], %[[VAL_24]] : i32
56-
!CHECK: %[[VAL_29:.*]] = arith.addi %[[VAL_28]], %[[VAL_21]] overflow<nuw> : i32
57-
!CHECK: %[[VAL_30:.*]] = arith.cmpi slt, %[[VAL_26]], %[[VAL_25]] : i32
58-
!CHECK: %[[VAL_31:.*]] = arith.select %[[VAL_30]], %[[VAL_20]], %[[VAL_29]] : i32
59-
!CHECK: %[[VAL_32:.*]] = omp.new_cli
60-
!CHECK: omp.canonical_loop(%[[VAL_32]]) %[[VAL_33:.*]] : i32 in range(%[[VAL_31]]) {
61-
!CHECK: %[[VAL_34:.*]] = arith.muli %[[VAL_33]], %[[VAL_19]] : i32
62-
!CHECK: %[[VAL_35:.*]] = arith.addi %[[VAL_17]], %[[VAL_34]] : i32
63-
!CHECK: hlfir.assign %[[VAL_35]] to %[[VAL_14]]#0 : i32, !fir.ref<i32>
64-
!CHECK: %[[VAL_36:.*]] = fir.alloca i32 {bindc_name = "j", pinned, uniq_name = "_QFomp_unroll_heuristic_nested02Ej"}
65-
!CHECK: %[[VAL_37:.*]]:2 = hlfir.declare %[[VAL_36]] {uniq_name = "_QFomp_unroll_heuristic_nested02Ej"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
66-
!CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32>
67-
!CHECK: %[[VAL_39:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
68-
!CHECK: %[[VAL_40:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
69-
!CHECK: %[[VAL_41:.*]] = arith.constant 0 : i32
70-
!CHECK: %[[VAL_42:.*]] = arith.constant 1 : i32
71-
!CHECK: %[[VAL_43:.*]] = arith.cmpi slt, %[[VAL_40]], %[[VAL_41]] : i32
72-
!CHECK: %[[VAL_44:.*]] = arith.subi %[[VAL_41]], %[[VAL_40]] : i32
73-
!CHECK: %[[VAL_45:.*]] = arith.select %[[VAL_43]], %[[VAL_44]], %[[VAL_40]] : i32
74-
!CHECK: %[[VAL_46:.*]] = arith.select %[[VAL_43]], %[[VAL_39]], %[[VAL_38]] : i32
75-
!CHECK: %[[VAL_47:.*]] = arith.select %[[VAL_43]], %[[VAL_38]], %[[VAL_39]] : i32
76-
!CHECK: %[[VAL_48:.*]] = arith.subi %[[VAL_47]], %[[VAL_46]] overflow<nuw> : i32
77-
!CHECK: %[[VAL_49:.*]] = arith.divui %[[VAL_48]], %[[VAL_45]] : i32
78-
!CHECK: %[[VAL_50:.*]] = arith.addi %[[VAL_49]], %[[VAL_42]] overflow<nuw> : i32
79-
!CHECK: %[[VAL_51:.*]] = arith.cmpi slt, %[[VAL_47]], %[[VAL_46]] : i32
80-
!CHECK: %[[VAL_52:.*]] = arith.select %[[VAL_51]], %[[VAL_41]], %[[VAL_50]] : i32
81-
!CHECK: %[[VAL_53:.*]] = omp.new_cli
82-
!CHECK: omp.canonical_loop(%[[VAL_53]]) %[[VAL_54:.*]] : i32 in range(%[[VAL_52]]) {
83-
!CHECK: %[[VAL_55:.*]] = arith.muli %[[VAL_54]], %[[VAL_40]] : i32
84-
!CHECK: %[[VAL_56:.*]] = arith.addi %[[VAL_38]], %[[VAL_55]] : i32
85-
!CHECK: hlfir.assign %[[VAL_56]] to %[[VAL_37]]#0 : i32, !fir.ref<i32>
86-
!CHECK: %[[VAL_57:.*]] = fir.load %[[VAL_14]]#0 : !fir.ref<i32>
87-
!CHECK: %[[VAL_58:.*]] = fir.load %[[VAL_37]]#0 : !fir.ref<i32>
88-
!CHECK: %[[VAL_59:.*]] = arith.addi %[[VAL_57]], %[[VAL_58]] : i32
89-
!CHECK: hlfir.assign %[[VAL_59]] to %[[VAL_12]]#0 : i32, !fir.ref<i32>
40+
!CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i32>
41+
!CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<i32>
42+
!CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32>
43+
!CHECK: %[[VAL_16:.*]] = arith.constant 0 : i32
44+
!CHECK: %[[VAL_17:.*]] = arith.constant 1 : i32
45+
!CHECK: %[[VAL_18:.*]] = arith.cmpi slt, %[[VAL_15]], %[[VAL_16]] : i32
46+
!CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_16]], %[[VAL_15]] : i32
47+
!CHECK: %[[VAL_20:.*]] = arith.select %[[VAL_18]], %[[VAL_19]], %[[VAL_15]] : i32
48+
!CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_18]], %[[VAL_14]], %[[VAL_13]] : i32
49+
!CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_18]], %[[VAL_13]], %[[VAL_14]] : i32
50+
!CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_21]] overflow<nuw> : i32
51+
!CHECK: %[[VAL_24:.*]] = arith.divui %[[VAL_23]], %[[VAL_20]] : i32
52+
!CHECK: %[[VAL_25:.*]] = arith.addi %[[VAL_24]], %[[VAL_17]] overflow<nuw> : i32
53+
!CHECK: %[[VAL_26:.*]] = arith.cmpi slt, %[[VAL_22]], %[[VAL_21]] : i32
54+
!CHECK: %[[VAL_27:.*]] = arith.select %[[VAL_26]], %[[VAL_16]], %[[VAL_25]] : i32
55+
!CHECK: %[[VAL_28:.*]] = omp.new_cli
56+
!CHECK: omp.canonical_loop(%[[VAL_28]]) %[[VAL_29:.*]] : i32 in range(%[[VAL_27]]) {
57+
!CHECK: %[[VAL_30:.*]] = arith.muli %[[VAL_29]], %[[VAL_15]] : i32
58+
!CHECK: %[[VAL_31:.*]] = arith.addi %[[VAL_13]], %[[VAL_30]] : i32
59+
!CHECK: hlfir.assign %[[VAL_31]] to %[[VAL_2]]#0 : i32, !fir.ref<i32>
60+
!CHECK: %[[VAL_32:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32>
61+
!CHECK: %[[VAL_33:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
62+
!CHECK: %[[VAL_34:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
63+
!CHECK: %[[VAL_35:.*]] = arith.constant 0 : i32
64+
!CHECK: %[[VAL_36:.*]] = arith.constant 1 : i32
65+
!CHECK: %[[VAL_37:.*]] = arith.cmpi slt, %[[VAL_34]], %[[VAL_35]] : i32
66+
!CHECK: %[[VAL_38:.*]] = arith.subi %[[VAL_35]], %[[VAL_34]] : i32
67+
!CHECK: %[[VAL_39:.*]] = arith.select %[[VAL_37]], %[[VAL_38]], %[[VAL_34]] : i32
68+
!CHECK: %[[VAL_40:.*]] = arith.select %[[VAL_37]], %[[VAL_33]], %[[VAL_32]] : i32
69+
!CHECK: %[[VAL_41:.*]] = arith.select %[[VAL_37]], %[[VAL_32]], %[[VAL_33]] : i32
70+
!CHECK: %[[VAL_42:.*]] = arith.subi %[[VAL_41]], %[[VAL_40]] overflow<nuw> : i32
71+
!CHECK: %[[VAL_43:.*]] = arith.divui %[[VAL_42]], %[[VAL_39]] : i32
72+
!CHECK: %[[VAL_44:.*]] = arith.addi %[[VAL_43]], %[[VAL_36]] overflow<nuw> : i32
73+
!CHECK: %[[VAL_45:.*]] = arith.cmpi slt, %[[VAL_41]], %[[VAL_40]] : i32
74+
!CHECK: %[[VAL_46:.*]] = arith.select %[[VAL_45]], %[[VAL_35]], %[[VAL_44]] : i32
75+
!CHECK: %[[VAL_47:.*]] = omp.new_cli
76+
!CHECK: omp.canonical_loop(%[[VAL_47]]) %[[VAL_48:.*]] : i32 in range(%[[VAL_46]]) {
77+
!CHECK: %[[VAL_49:.*]] = arith.muli %[[VAL_48]], %[[VAL_34]] : i32
78+
!CHECK: %[[VAL_50:.*]] = arith.addi %[[VAL_32]], %[[VAL_49]] : i32
79+
!CHECK: hlfir.assign %[[VAL_50]] to %[[VAL_7]]#0 : i32, !fir.ref<i32>
80+
!CHECK: %[[VAL_51:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<i32>
81+
!CHECK: %[[VAL_52:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<i32>
82+
!CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_51]], %[[VAL_52]] : i32
83+
!CHECK: hlfir.assign %[[VAL_53]] to %[[VAL_12]]#0 : i32, !fir.ref<i32>
9084
!CHECK: omp.terminator
9185
!CHECK: }
92-
!CHECK: omp.unroll_heuristic(%[[VAL_53]])
86+
!CHECK: omp.unroll_heuristic(%[[VAL_47]])
9387
!CHECK: omp.terminator
9488
!CHECK: }
95-
!CHECK: omp.unroll_heuristic(%[[VAL_32]])
89+
!CHECK: omp.unroll_heuristic(%[[VAL_28]])
9690
!CHECK: return
9791
!CHECK: }

0 commit comments

Comments
 (0)