Skip to content

Commit 3dbb055

Browse files
authored
[flang] Generate valid IR on GOTO DO body (#66084)
Flang was generating invalid IR when there was a GOTO to the body of a DO loop. This happened because the value of step, computed at the beginning of the loop, was being reused at the end of the loop, that, for unstructured loops, is in another basic block. Because of this, a GOTO could skip the beginning of the loop, that defined step, and yet try to use it at the end of the loop, which is invalid. Instead of reusing the step value, it can be recomputed if it is a constant, or stored and loaded to/from a temporary variable, for non-constant step expressions. Note that, while this change prevents the generation of invalid IR on the presence of jumps to DO loop bodies, what happens if the program reaches the end of a DO loop without ever passing through its beginning is undefined behavior, as some control variables, such as trip, will be uninitialized. It doesn't seem worth the effort and overhead to ensure this legacy extension will behave correctly in this case. This is consistent with at least gfortran, that doesn't behave correctly if step is not equal to one. Fixes: #65036
1 parent 7e74446 commit 3dbb055

File tree

7 files changed

+309
-40
lines changed

7 files changed

+309
-40
lines changed

flang/lib/Lower/Bridge.cpp

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,14 @@ struct IncrementLoopInfo {
112112
llvm::SmallVector<const Fortran::semantics::Symbol *> localInitSymList;
113113
llvm::SmallVector<const Fortran::semantics::Symbol *> sharedSymList;
114114
mlir::Value loopVariable = nullptr;
115-
mlir::Value stepValue = nullptr; // possible uses in multiple blocks
116115

117116
// Data members for structured loops.
118117
fir::DoLoopOp doLoop = nullptr;
119118

120119
// Data members for unstructured loops.
121120
bool hasRealControl = false;
122121
mlir::Value tripVariable = nullptr;
122+
mlir::Value stepVariable = nullptr;
123123
mlir::Block *headerBlock = nullptr; // loop entry and test block
124124
mlir::Block *maskBlock = nullptr; // concurrent loop mask block
125125
mlir::Block *bodyBlock = nullptr; // first loop body block
@@ -1738,29 +1738,45 @@ class FirConverter : public Fortran::lower::AbstractConverter {
17381738
genFIR(endDoEval, unstructuredContext);
17391739
}
17401740

1741+
/// Generate FIR to evaluate loop control values (lower, upper and step).
1742+
mlir::Value genControlValue(const Fortran::lower::SomeExpr *expr,
1743+
const IncrementLoopInfo &info,
1744+
bool *isConst = nullptr) {
1745+
mlir::Location loc = toLocation();
1746+
mlir::Type controlType = info.isStructured() ? builder->getIndexType()
1747+
: info.getLoopVariableType();
1748+
Fortran::lower::StatementContext stmtCtx;
1749+
if (expr) {
1750+
if (isConst)
1751+
*isConst = Fortran::evaluate::IsConstantExpr(*expr);
1752+
return builder->createConvert(loc, controlType,
1753+
createFIRExpr(loc, expr, stmtCtx));
1754+
}
1755+
1756+
if (isConst)
1757+
*isConst = true;
1758+
if (info.hasRealControl)
1759+
return builder->createRealConstant(loc, controlType, 1u);
1760+
return builder->createIntegerConstant(loc, controlType, 1); // step
1761+
}
1762+
17411763
/// Generate FIR to begin a structured or unstructured increment loop nest.
17421764
void genFIRIncrementLoopBegin(IncrementLoopNestInfo &incrementLoopNestInfo) {
17431765
assert(!incrementLoopNestInfo.empty() && "empty loop nest");
17441766
mlir::Location loc = toLocation();
1745-
auto genControlValue = [&](const Fortran::lower::SomeExpr *expr,
1746-
const IncrementLoopInfo &info) {
1747-
mlir::Type controlType = info.isStructured() ? builder->getIndexType()
1748-
: info.getLoopVariableType();
1749-
Fortran::lower::StatementContext stmtCtx;
1750-
if (expr)
1751-
return builder->createConvert(loc, controlType,
1752-
createFIRExpr(loc, expr, stmtCtx));
1753-
1754-
if (info.hasRealControl)
1755-
return builder->createRealConstant(loc, controlType, 1u);
1756-
return builder->createIntegerConstant(loc, controlType, 1); // step
1757-
};
17581767
for (IncrementLoopInfo &info : incrementLoopNestInfo) {
17591768
info.loopVariable =
17601769
genLoopVariableAddress(loc, info.loopVariableSym, info.isUnordered);
17611770
mlir::Value lowerValue = genControlValue(info.lowerExpr, info);
17621771
mlir::Value upperValue = genControlValue(info.upperExpr, info);
1763-
info.stepValue = genControlValue(info.stepExpr, info);
1772+
bool isConst = true;
1773+
mlir::Value stepValue = genControlValue(
1774+
info.stepExpr, info, info.isStructured() ? nullptr : &isConst);
1775+
// Use a temp variable for unstructured loops with non-const step.
1776+
if (!isConst) {
1777+
info.stepVariable = builder->createTemporary(loc, stepValue.getType());
1778+
builder->create<fir::StoreOp>(loc, stepValue, info.stepVariable);
1779+
}
17641780

17651781
// Structured loop - generate fir.do_loop.
17661782
if (info.isStructured()) {
@@ -1769,14 +1785,14 @@ class FirConverter : public Fortran::lower::AbstractConverter {
17691785
if (info.isUnordered) {
17701786
// The loop variable value is explicitly updated.
17711787
info.doLoop = builder->create<fir::DoLoopOp>(
1772-
loc, lowerValue, upperValue, info.stepValue, /*unordered=*/true);
1788+
loc, lowerValue, upperValue, stepValue, /*unordered=*/true);
17731789
builder->setInsertionPointToStart(info.doLoop.getBody());
17741790
loopValue = builder->createConvert(loc, loopVarType,
17751791
info.doLoop.getInductionVar());
17761792
} else {
17771793
// The loop variable is a doLoop op argument.
17781794
info.doLoop = builder->create<fir::DoLoopOp>(
1779-
loc, lowerValue, upperValue, info.stepValue, /*unordered=*/false,
1795+
loc, lowerValue, upperValue, stepValue, /*unordered=*/false,
17801796
/*finalCountValue=*/true,
17811797
builder->createConvert(loc, loopVarType, lowerValue));
17821798
builder->setInsertionPointToStart(info.doLoop.getBody());
@@ -1805,18 +1821,17 @@ class FirConverter : public Fortran::lower::AbstractConverter {
18051821
auto diff1 =
18061822
builder->create<mlir::arith::SubFOp>(loc, upperValue, lowerValue);
18071823
auto diff2 =
1808-
builder->create<mlir::arith::AddFOp>(loc, diff1, info.stepValue);
1809-
tripCount =
1810-
builder->create<mlir::arith::DivFOp>(loc, diff2, info.stepValue);
1824+
builder->create<mlir::arith::AddFOp>(loc, diff1, stepValue);
1825+
tripCount = builder->create<mlir::arith::DivFOp>(loc, diff2, stepValue);
18111826
tripCount =
18121827
builder->createConvert(loc, builder->getIndexType(), tripCount);
18131828
} else {
18141829
auto diff1 =
18151830
builder->create<mlir::arith::SubIOp>(loc, upperValue, lowerValue);
18161831
auto diff2 =
1817-
builder->create<mlir::arith::AddIOp>(loc, diff1, info.stepValue);
1832+
builder->create<mlir::arith::AddIOp>(loc, diff1, stepValue);
18181833
tripCount =
1819-
builder->create<mlir::arith::DivSIOp>(loc, diff2, info.stepValue);
1834+
builder->create<mlir::arith::DivSIOp>(loc, diff2, stepValue);
18201835
}
18211836
if (forceLoopToExecuteOnce) { // minimum tripCount is 1
18221837
mlir::Value one =
@@ -1904,12 +1919,15 @@ class FirConverter : public Fortran::lower::AbstractConverter {
19041919
tripCount = builder->create<mlir::arith::SubIOp>(loc, tripCount, one);
19051920
builder->create<fir::StoreOp>(loc, tripCount, info.tripVariable);
19061921
mlir::Value value = builder->create<fir::LoadOp>(loc, info.loopVariable);
1922+
mlir::Value step;
1923+
if (info.stepVariable)
1924+
step = builder->create<fir::LoadOp>(loc, info.stepVariable);
1925+
else
1926+
step = genControlValue(info.stepExpr, info);
19071927
if (info.hasRealControl)
1908-
value =
1909-
builder->create<mlir::arith::AddFOp>(loc, value, info.stepValue);
1928+
value = builder->create<mlir::arith::AddFOp>(loc, value, step);
19101929
else
1911-
value =
1912-
builder->create<mlir::arith::AddIOp>(loc, value, info.stepValue);
1930+
value = builder->create<mlir::arith::AddIOp>(loc, value, step);
19131931
builder->create<fir::StoreOp>(loc, value, info.loopVariable);
19141932

19151933
genBranch(info.headerBlock);
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
! RUN: bbc --hlfir -o - %s | FileCheck %s
2+
3+
! Test jumping to the body of a do loop.
4+
subroutine sub1()
5+
! CHECK-LABEL: func @_QPsub1() {
6+
implicit none
7+
integer :: i
8+
external foo
9+
! CHECK: %[[C2:.*]] = arith.constant 2 : i32
10+
! CHECK: %[[C0:.*]] = arith.constant 0 : i32
11+
! CHECK: %[[C1:.*]] = arith.constant 1 : i32
12+
! CHECK: %[[TRIP:.*]] = fir.alloca i32
13+
! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", {{.*}}}
14+
! CHECK: %[[I:.*]]:2 = hlfir.declare %[[I_REF]] {uniq_name = "_QFsub1Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
15+
16+
do i = 1, 3
17+
if (i .eq. 2) goto 70
18+
! CHECK: %[[TMP1:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
19+
! CHECK: %[[COND:.*]] = arith.cmpi eq, %[[TMP1]], %[[C2]] : i32
20+
! CHECK: cf.cond_br %[[COND]], ^[[BODY:.*]], ^{{.*}}
21+
22+
end do
23+
24+
call foo
25+
! CHECK: fir.call @_QPfoo()
26+
27+
do i = 1, 2
28+
! CHECK: fir.store %[[C2]] to %[[TRIP]] : !fir.ref<i32>
29+
! CHECK: fir.store %[[C1]] to %[[I]]#1 : !fir.ref<i32>
30+
! CHECK: cf.br ^[[HEADER:.*]]
31+
! CHECK: ^[[HEADER]]:
32+
! CHECK: %[[TMP2:.*]] = fir.load %[[TRIP]] : !fir.ref<i32>
33+
! CHECK: %[[TMP3:.*]] = arith.cmpi sgt, %[[TMP2]], %[[C0]] : i32
34+
! CHECK: cf.cond_br %[[TMP3]], ^[[BODY]], ^[[EXIT:.*]]
35+
36+
70 call foo
37+
! CHECK: ^[[BODY]]:
38+
! CHECK: fir.call @_QPfoo()
39+
! CHECK: %[[TMP4:.*]] = fir.load %[[TRIP]] : !fir.ref<i32>
40+
! CHECK: %[[TMP5:.*]] = arith.subi %[[TMP4]], %[[C1]] : i32
41+
! CHECK: fir.store %[[TMP5]] to %[[TRIP]] : !fir.ref<i32>
42+
! CHECK: %[[TMP6:.*]] = fir.load %[[I]]#1 : !fir.ref<i32>
43+
! CHECK: %[[TMP7:.*]] = arith.addi %[[TMP6]], %[[C1]] : i32
44+
! CHECK: fir.store %[[TMP7]] to %[[I]]#1 : !fir.ref<i32>
45+
! CHECK: cf.br ^[[HEADER]]
46+
end do
47+
end subroutine
48+
! CHECK: ^[[EXIT]]:
49+
! CHECK: return
50+
! CHECK: }
51+
52+
! Test jumping to the body of a do loop with a step expression.
53+
subroutine sub2()
54+
! CHECK-LABEL: func @_QPsub2() {
55+
implicit none
56+
integer :: i, j
57+
external foo
58+
! CHECK: %[[C_7:.*]] = arith.constant -7 : i32
59+
! CHECK: %[[C8:.*]] = arith.constant 8 : i32
60+
! CHECK: %[[C2:.*]] = arith.constant 2 : i32
61+
! CHECK: %[[C0:.*]] = arith.constant 0 : i32
62+
! CHECK: %[[C3:.*]] = arith.constant 3 : i32
63+
! CHECK: %[[C1:.*]] = arith.constant 1 : i32
64+
! CHECK: %[[TRIP:.*]] = fir.alloca i32
65+
! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", {{.*}}}
66+
! CHECK: %[[I:.*]]:2 = hlfir.declare %[[I_REF]] {uniq_name = "_QFsub2Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
67+
! CHECK: %[[J_REF:.*]] = fir.alloca i32 {bindc_name = "j", {{.*}}}
68+
! CHECK: %[[J:.*]]:2 = hlfir.declare %[[J_REF]] {uniq_name = "_QFsub2Ej"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
69+
70+
do i = 1, 3
71+
if (i .eq. 2) goto 70
72+
! CHECK: %[[TMP1:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
73+
! CHECK: %[[COND:.*]] = arith.cmpi eq, %[[TMP1]], %[[C2]] : i32
74+
! CHECK: cf.cond_br %[[COND]], ^[[BODY:.*]], ^{{.*}}
75+
76+
end do
77+
78+
call foo
79+
! CHECK: fir.call @_QPfoo()
80+
81+
j = 3
82+
! CHECK: hlfir.assign %[[C3]] to %[[J]]#0 : i32, !fir.ref<i32>
83+
84+
do i = 1, 2, 3 * j - 8
85+
! CHECK: %[[TMP2:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
86+
! CHECK: %[[TMP3:.*]] = arith.muli %[[TMP2]], %[[C3]] : i32
87+
! CHECK: %[[STEP:.*]] = arith.subi %[[TMP3]], %[[C8]] : i32
88+
! CHECK: fir.store %[[STEP]] to %[[STEP_VAR:.*]] : !fir.ref<i32>
89+
! CHECK: %[[TMP4:.*]] = arith.addi %[[TMP3]], %[[C_7]] : i32
90+
! CHECK: %[[TMP5:.*]] = arith.divsi %[[TMP4]], %[[STEP]] : i32
91+
! CHECK: fir.store %[[TMP5]] to %[[TRIP]] : !fir.ref<i32>
92+
! CHECK: fir.store %[[C1]] to %[[I]]#1 : !fir.ref<i32>
93+
! CHECK: cf.br ^[[HEADER:.*]]
94+
! CHECK: ^[[HEADER]]:
95+
! CHECK: %[[TMP6:.*]] = fir.load %[[TRIP]] : !fir.ref<i32>
96+
! CHECK: %[[TMP7:.*]] = arith.cmpi sgt, %[[TMP6]], %[[C0]] : i32
97+
! CHECK: cf.cond_br %[[TMP7]], ^[[BODY]], ^[[EXIT:.*]]
98+
99+
70 call foo
100+
! CHECK: ^[[BODY]]:
101+
! CHECK: fir.call @_QPfoo()
102+
! CHECK: %[[TMP8:.*]] = fir.load %[[TRIP]] : !fir.ref<i32>
103+
! CHECK: %[[TMP9:.*]] = arith.subi %[[TMP8]], %[[C1]] : i32
104+
! CHECK: fir.store %[[TMP9]] to %[[TRIP]] : !fir.ref<i32>
105+
! CHECK: %[[TMP10:.*]] = fir.load %[[I]]#1 : !fir.ref<i32>
106+
! CHECK: %[[STEP_VAL:.*]] = fir.load %[[STEP_VAR]] : !fir.ref<i32>
107+
! CHECK: %[[TMP11:.*]] = arith.addi %[[TMP10]], %[[STEP_VAL]] : i32
108+
! CHECK: fir.store %[[TMP11]] to %[[I]]#1 : !fir.ref<i32>
109+
! CHECK: cf.br ^[[HEADER]]
110+
end do
111+
end subroutine
112+
! CHECK: ^[[EXIT]]:
113+
! CHECK: return
114+
! CHECK: }

flang/test/Lower/do_loop.f90

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ subroutine loop_with_real_control(s,e,st)
245245
! CHECK-DAG: %[[S:.*]] = fir.load %[[S_REF]] : !fir.ref<f32>
246246
! CHECK-DAG: %[[E:.*]] = fir.load %[[E_REF]] : !fir.ref<f32>
247247
! CHECK-DAG: %[[ST:.*]] = fir.load %[[ST_REF]] : !fir.ref<f32>
248+
! CHECK: fir.store %[[ST]] to %[[ST_VAR:.*]] : !fir.ref<f32>
248249
real :: x, s, e, st
249250

250251
! CHECK: %[[DIFF:.*]] = arith.subf %[[E]], %[[S]] {{.*}}: f32
@@ -267,7 +268,8 @@ subroutine loop_with_real_control(s,e,st)
267268
! CHECK: %[[INC:.*]] = arith.subi %[[INDEX2]], %[[C1]] : index
268269
! CHECK: fir.store %[[INC]] to %[[INDEX_REF]] : !fir.ref<index>
269270
! CHECK: %[[X2:.*]] = fir.load %[[X_REF]] : !fir.ref<f32>
270-
! CHECK: %[[XINC:.*]] = arith.addf %[[X2]], %[[ST]] {{.*}}: f32
271+
! CHECK: %[[ST_VAL:.*]] = fir.load %[[ST_VAR]] : !fir.ref<f32>
272+
! CHECK: %[[XINC:.*]] = arith.addf %[[X2]], %[[ST_VAL]] {{.*}}: f32
271273
! CHECK: fir.store %[[XINC]] to %[[X_REF]] : !fir.ref<f32>
272274
! CHECK: br ^[[HDR]]
273275
end do

flang/test/Lower/do_loop_unstructured.f90

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ subroutine simple_unstructured()
3737
! CHECK: %[[TRIP_VAR_NEXT:.*]] = arith.subi %[[TRIP_VAR]], %[[ONE_1]] : i32
3838
! CHECK: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
3939
! CHECK: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref<i32>
40-
! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_ONE]] : i32
40+
! CHECK: %[[STEP_ONE_2:.*]] = arith.constant 1 : i32
41+
! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_ONE_2]] : i32
4142
! CHECK: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
4243
! CHECK: cf.br ^[[HEADER]]
4344
! CHECK: ^[[EXIT]]:
@@ -75,7 +76,8 @@ subroutine simple_unstructured_with_step()
7576
! CHECK: %[[TRIP_VAR_NEXT:.*]] = arith.subi %[[TRIP_VAR]], %[[ONE_1]] : i32
7677
! CHECK: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
7778
! CHECK: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref<i32>
78-
! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP]] : i32
79+
! CHECK: %[[STEP_2:.*]] = arith.constant 2 : i32
80+
! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_2]] : i32
7981
! CHECK: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
8082
! CHECK: cf.br ^[[HEADER]]
8183
! CHECK: ^[[EXIT]]:
@@ -151,7 +153,8 @@ subroutine nested_unstructured()
151153
! CHECK: %[[TRIP_VAR_K_NEXT:.*]] = arith.subi %[[TRIP_VAR_K]], %[[ONE_1]] : i32
152154
! CHECK: fir.store %[[TRIP_VAR_K_NEXT]] to %[[TRIP_VAR_K_REF]] : !fir.ref<i32>
153155
! CHECK: %[[LOOP_VAR_K:.*]] = fir.load %[[LOOP_VAR_K_REF]] : !fir.ref<i32>
154-
! CHECK: %[[LOOP_VAR_K_NEXT:.*]] = arith.addi %[[LOOP_VAR_K]], %[[K_STEP]] : i32
156+
! CHECK: %[[K_STEP_2:.*]] = arith.constant 1 : i32
157+
! CHECK: %[[LOOP_VAR_K_NEXT:.*]] = arith.addi %[[LOOP_VAR_K]], %[[K_STEP_2]] : i32
155158
! CHECK: fir.store %[[LOOP_VAR_K_NEXT]] to %[[LOOP_VAR_K_REF]] : !fir.ref<i32>
156159
! CHECK: cf.br ^[[HEADER_K]]
157160
! CHECK: ^[[EXIT_K]]:
@@ -160,7 +163,8 @@ subroutine nested_unstructured()
160163
! CHECK: %[[TRIP_VAR_J_NEXT:.*]] = arith.subi %[[TRIP_VAR_J]], %[[ONE_1]] : i32
161164
! CHECK: fir.store %[[TRIP_VAR_J_NEXT]] to %[[TRIP_VAR_J_REF]] : !fir.ref<i32>
162165
! CHECK: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
163-
! CHECK: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %[[J_STEP]] : i32
166+
! CHECK: %[[J_STEP_2:.*]] = arith.constant 1 : i32
167+
! CHECK: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %[[J_STEP_2]] : i32
164168
! CHECK: fir.store %[[LOOP_VAR_J_NEXT]] to %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
165169
! CHECK: cf.br ^[[HEADER_J]]
166170
! CHECK: ^[[EXIT_J]]:
@@ -169,7 +173,8 @@ subroutine nested_unstructured()
169173
! CHECK: %[[TRIP_VAR_I_NEXT:.*]] = arith.subi %[[TRIP_VAR_I]], %[[ONE_1]] : i32
170174
! CHECK: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
171175
! CHECK: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
172-
! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP]] : i32
176+
! CHECK: %[[I_STEP_2:.*]] = arith.constant 1 : i32
177+
! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] : i32
173178
! CHECK: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
174179
! CHECK: cf.br ^[[HEADER_I]]
175180
! CHECK: ^[[EXIT_I]]:
@@ -215,7 +220,8 @@ subroutine nested_structured_in_unstructured()
215220
! CHECK: %[[TRIP_VAR_I_NEXT:.*]] = arith.subi %[[TRIP_VAR_I]], %[[C1_3]] : i32
216221
! CHECK: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
217222
! CHECK: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
218-
! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %c1_i32_0 : i32
223+
! CHECK: %[[I_STEP_2:.*]] = arith.constant 1 : i32
224+
! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] : i32
219225
! CHECK: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
220226
! CHECK: cf.br ^[[HEADER]]
221227
! CHECK: ^[[EXIT]]:

0 commit comments

Comments
 (0)