Skip to content

Commit dfa13f1

Browse files
schweitzpgijeanPerier
authored andcommitted
Fix vector subscript in vector subscript (in vector subscri...)
1 parent bf61151 commit dfa13f1

File tree

2 files changed

+111
-42
lines changed

2 files changed

+111
-42
lines changed

flang/lib/Lower/ConvertExpr.cpp

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3482,32 +3482,6 @@ class ArrayExprLowering {
34823482
}
34833483
}
34843484

3485-
/// Entry point for when an array expression appears on the lhs of an
3486-
/// assignment. In the default case, the rhs is fully evaluated prior to any
3487-
/// of the results being written back to the lhs. (CopyInCopyOut semantics.)
3488-
static fir::ArrayLoadOp lowerArraySubspace(
3489-
Fortran::lower::AbstractConverter &converter,
3490-
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx,
3491-
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &expr) {
3492-
ArrayExprLowering ael{converter, stmtCtx, symMap,
3493-
ConstituentSemantics::CopyInCopyOut};
3494-
return ael.lowerArraySubspace(expr);
3495-
}
3496-
3497-
fir::ArrayLoadOp lowerArraySubspace(
3498-
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &exp) {
3499-
return std::visit(
3500-
[&](const auto &e) {
3501-
auto f = genarr(e);
3502-
auto exv = f(IterationSpace{});
3503-
if (auto *defOp = fir::getBase(exv).getDefiningOp())
3504-
if (auto arrLd = mlir::dyn_cast<fir::ArrayLoadOp>(defOp))
3505-
return arrLd;
3506-
fir::emitFatalError(getLoc(), "array must be loaded");
3507-
},
3508-
exp.u);
3509-
}
3510-
35113485
/// Entry point for when an array expression appears in a context where the
35123486
/// result must be boxed. (BoxValue semantics.)
35133487
static ExtValue lowerBoxedArrayExpression(
@@ -5104,30 +5078,22 @@ class ArrayExprLowering {
51045078
// vector subscript with replicated values.
51055079
assert(!isBoxValue() &&
51065080
"fir.box cannot be created with vector subscripts");
5107-
if (Fortran::evaluate::HasVectorSubscript(toEvExpr(e)))
5108-
TODO(loc, "vector subscript of vector subscript");
51095081
auto base = x.base();
51105082
auto exv = genArrayBase(base);
51115083
auto arrExpr = ignoreEvConvert(e);
5112-
auto arrLoad =
5113-
lowerArraySubspace(converter, symMap, stmtCtx, arrExpr);
5114-
auto arrLd = arrLoad.getResult();
5115-
auto eleTy =
5116-
arrLd.getType().cast<fir::SequenceType>().getEleTy();
5084+
auto saveSemant = semant;
5085+
semant = ConstituentSemantics::RefTransparent;
5086+
auto genArrFetch = genarr(arrExpr);
5087+
semant = saveSemant;
51175088
auto currentPC = pc;
51185089
auto dim = sub.index();
51195090
auto lb =
51205091
fir::factory::readLowerBound(builder, loc, exv, dim, one);
5121-
auto arrLdTypeParams = arrLoad.typeparams();
51225092
pc = [=](IterSpace iters) {
51235093
IterationSpace newIters = currentPC(iters);
5124-
auto iter = newIters.iterVec()[dim];
5125-
// TODO: Next line, delete?
5126-
auto resTy = adjustedArrayElementType(eleTy);
5127-
auto fetch = builder.create<fir::ArrayFetchOp>(
5128-
loc, resTy, arrLd, mlir::ValueRange{iter},
5129-
arrLdTypeParams);
5130-
auto cast = builder.createConvert(loc, idxTy, fetch);
5094+
auto fetch = genArrFetch(newIters);
5095+
auto cast =
5096+
builder.createConvert(loc, idxTy, fir::getBase(fetch));
51315097
auto val = builder.create<mlir::arith::SubIOp>(loc, idxTy,
51325098
cast, lb);
51335099
newIters.setIndexValue(dim, val);
@@ -5136,7 +5102,7 @@ class ArrayExprLowering {
51365102
// Create a slice with the vector size so that the shape
51375103
// of array reference is correctly computed in later phase,
51385104
// even though this is not a triplet.
5139-
auto vectorSubscriptShape = getShape(arrLoad);
5105+
auto vectorSubscriptShape = getShape(arrayOperands.back());
51405106
assert(vectorSubscriptShape.size() == 1);
51415107
trips.push_back(one);
51425108
trips.push_back(vectorSubscriptShape[0]);

flang/test/Lower/array-expression-subscript.f90

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,112 @@ subroutine test1b(a,b,c)
9696
b(c(1:20:2)) = a
9797
end subroutine test1b
9898

99+
! CHECK-LABEL: func @_QPtest1c(
100+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<10xi32>>, %[[VAL_2:.*]]: !fir.ref<!fir.array<20xi32>>, %[[VAL_3:.*]]: !fir.ref<!fir.array<10xi32>>) {
101+
! CHECK: return
102+
! CHECK: }
99103
subroutine test1c(a,b,c,d)
100104
integer :: a(10), b(10), d(10), c(20)
101105

102106
! flang: parser FAIL (final position)
103107
!a = b(d(c(1:20:2))
104108
end subroutine test1c
109+
110+
111+
! CHECK-LABEL: func @_QPtest2a(
112+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<10xi32>>, %[[VAL_2:.*]]: !fir.ref<!fir.array<10xi32>>, %[[VAL_3:.*]]: !fir.ref<!fir.array<10xi32>>) {
113+
! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index
114+
! CHECK: %[[VAL_5:.*]] = arith.constant 10 : index
115+
! CHECK: %[[VAL_6:.*]] = arith.constant 10 : index
116+
! CHECK: %[[VAL_7:.*]] = arith.constant 10 : index
117+
! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
118+
! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_0]](%[[VAL_8]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.array<10xi32>
119+
! CHECK: %[[VAL_10:.*]] = arith.constant 10 : i64
120+
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i64) -> index
121+
! CHECK: %[[VAL_12:.*]] = arith.constant 1 : index
122+
! CHECK: %[[VAL_13:.*]] = arith.constant 1 : index
123+
! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1>
124+
! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_3]](%[[VAL_14]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.array<10xi32>
125+
! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
126+
! CHECK: %[[VAL_17:.*]] = fir.slice %[[VAL_13]], %[[VAL_7]], %[[VAL_13]] : (index, index, index) -> !fir.slice<1>
127+
! CHECK: %[[VAL_18:.*]] = fir.array_load %[[VAL_2]](%[[VAL_16]]) {{\[}}%[[VAL_17]]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.array<10xi32>
128+
! CHECK: %[[VAL_19:.*]] = arith.constant 0 : index
129+
! CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_7]], %[[VAL_13]] : index
130+
! CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_20]], %[[VAL_13]] : index
131+
! CHECK: %[[VAL_22:.*]] = arith.divsi %[[VAL_21]], %[[VAL_13]] : index
132+
! CHECK: %[[VAL_23:.*]] = arith.cmpi sgt, %[[VAL_22]], %[[VAL_19]] : index
133+
! CHECK: %[[VAL_24:.*]] = select %[[VAL_23]], %[[VAL_22]], %[[VAL_19]] : index
134+
! CHECK: %[[VAL_25:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
135+
! CHECK: %[[VAL_26:.*]] = fir.slice %[[VAL_12]], %[[VAL_24]], %[[VAL_12]] : (index, index, index) -> !fir.slice<1>
136+
! CHECK: %[[VAL_27:.*]] = fir.array_load %[[VAL_1]](%[[VAL_25]]) {{\[}}%[[VAL_26]]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.array<10xi32>
137+
! CHECK: %[[VAL_28:.*]] = arith.constant 1 : index
138+
! CHECK: %[[VAL_29:.*]] = arith.constant 0 : index
139+
! CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_11]], %[[VAL_28]] : index
140+
! CHECK: %[[VAL_31:.*]] = fir.do_loop %[[VAL_32:.*]] = %[[VAL_29]] to %[[VAL_30]] step %[[VAL_28]] unordered iter_args(%[[VAL_33:.*]] = %[[VAL_9]]) -> (!fir.array<10xi32>) {
141+
! CHECK: %[[VAL_34:.*]] = fir.array_fetch %[[VAL_15]], %[[VAL_32]] : (!fir.array<10xi32>, index) -> i32
142+
! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_34]] : (i32) -> index
143+
! CHECK: %[[VAL_36:.*]] = arith.subi %[[VAL_35]], %[[VAL_13]] : index
144+
! CHECK: %[[VAL_37:.*]] = fir.array_fetch %[[VAL_18]], %[[VAL_36]] : (!fir.array<10xi32>, index) -> i32
145+
! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (i32) -> index
146+
! CHECK: %[[VAL_39:.*]] = arith.subi %[[VAL_38]], %[[VAL_12]] : index
147+
! CHECK: %[[VAL_40:.*]] = fir.array_fetch %[[VAL_27]], %[[VAL_39]] : (!fir.array<10xi32>, index) -> i32
148+
! CHECK: %[[VAL_41:.*]] = fir.array_update %[[VAL_33]], %[[VAL_40]], %[[VAL_32]] : (!fir.array<10xi32>, i32, index) -> !fir.array<10xi32>
149+
! CHECK: fir.result %[[VAL_41]] : !fir.array<10xi32>
150+
! CHECK: }
151+
! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_42:.*]] to %[[VAL_0]] : !fir.array<10xi32>, !fir.array<10xi32>, !fir.ref<!fir.array<10xi32>>
152+
! CHECK: return
153+
! CHECK: }
154+
subroutine test2a(a,b,c,d)
155+
integer :: a(10), b(10), c(10), d(10)
156+
157+
a = b(c(d))
158+
end subroutine test2a
159+
160+
! CHECK-LABEL: func @_QPtest2b(
161+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<10xi32>>, %[[VAL_2:.*]]: !fir.ref<!fir.array<10xi32>>, %[[VAL_3:.*]]: !fir.ref<!fir.array<10xi32>>) {
162+
! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index
163+
! CHECK: %[[VAL_5:.*]] = arith.constant 10 : index
164+
! CHECK: %[[VAL_6:.*]] = arith.constant 10 : index
165+
! CHECK: %[[VAL_7:.*]] = arith.constant 10 : index
166+
! CHECK: %[[VAL_8:.*]] = arith.constant 1 : index
167+
! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index
168+
! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1>
169+
! CHECK: %[[VAL_11:.*]] = fir.array_load %[[VAL_3]](%[[VAL_10]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.array<10xi32>
170+
! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
171+
! CHECK: %[[VAL_13:.*]] = fir.slice %[[VAL_9]], %[[VAL_7]], %[[VAL_9]] : (index, index, index) -> !fir.slice<1>
172+
! CHECK: %[[VAL_14:.*]] = fir.array_load %[[VAL_2]](%[[VAL_12]]) {{\[}}%[[VAL_13]]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.array<10xi32>
173+
! CHECK: %[[VAL_15:.*]] = arith.constant 0 : index
174+
! CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_7]], %[[VAL_9]] : index
175+
! CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_16]], %[[VAL_9]] : index
176+
! CHECK: %[[VAL_18:.*]] = arith.divsi %[[VAL_17]], %[[VAL_9]] : index
177+
! CHECK: %[[VAL_19:.*]] = arith.cmpi sgt, %[[VAL_18]], %[[VAL_15]] : index
178+
! CHECK: %[[VAL_20:.*]] = select %[[VAL_19]], %[[VAL_18]], %[[VAL_15]] : index
179+
! CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
180+
! CHECK: %[[VAL_22:.*]] = fir.slice %[[VAL_8]], %[[VAL_20]], %[[VAL_8]] : (index, index, index) -> !fir.slice<1>
181+
! CHECK: %[[VAL_23:.*]] = fir.array_load %[[VAL_1]](%[[VAL_21]]) {{\[}}%[[VAL_22]]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.array<10xi32>
182+
! CHECK: %[[VAL_24:.*]] = arith.constant 10 : i64
183+
! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i64) -> index
184+
! CHECK: %[[VAL_26:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
185+
! CHECK: %[[VAL_27:.*]] = fir.array_load %[[VAL_0]](%[[VAL_26]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.array<10xi32>
186+
! CHECK: %[[VAL_28:.*]] = arith.constant 1 : index
187+
! CHECK: %[[VAL_29:.*]] = arith.constant 0 : index
188+
! CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_25]], %[[VAL_28]] : index
189+
! CHECK: %[[VAL_31:.*]] = fir.do_loop %[[VAL_32:.*]] = %[[VAL_29]] to %[[VAL_30]] step %[[VAL_28]] unordered iter_args(%[[VAL_33:.*]] = %[[VAL_23]]) -> (!fir.array<10xi32>) {
190+
! CHECK: %[[VAL_34:.*]] = fir.array_fetch %[[VAL_27]], %[[VAL_32]] : (!fir.array<10xi32>, index) -> i32
191+
! CHECK: %[[VAL_35:.*]] = fir.array_fetch %[[VAL_11]], %[[VAL_32]] : (!fir.array<10xi32>, index) -> i32
192+
! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i32) -> index
193+
! CHECK: %[[VAL_37:.*]] = arith.subi %[[VAL_36]], %[[VAL_9]] : index
194+
! CHECK: %[[VAL_38:.*]] = fir.array_fetch %[[VAL_14]], %[[VAL_37]] : (!fir.array<10xi32>, index) -> i32
195+
! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_38]] : (i32) -> index
196+
! CHECK: %[[VAL_40:.*]] = arith.subi %[[VAL_39]], %[[VAL_8]] : index
197+
! CHECK: %[[VAL_41:.*]] = fir.array_update %[[VAL_33]], %[[VAL_34]], %[[VAL_40]] : (!fir.array<10xi32>, i32, index) -> !fir.array<10xi32>
198+
! CHECK: fir.result %[[VAL_41]] : !fir.array<10xi32>
199+
! CHECK: }
200+
! CHECK: fir.array_merge_store %[[VAL_23]], %[[VAL_42:.*]] to %[[VAL_1]]{{\[}}%[[VAL_22]]] : !fir.array<10xi32>, !fir.array<10xi32>, !fir.ref<!fir.array<10xi32>>, !fir.slice<1>
201+
! CHECK: return
202+
! CHECK: }
203+
subroutine test2b(a,b,c,d)
204+
integer :: a(10), b(10), c(10), d(10)
205+
206+
b(c(d)) = a
207+
end subroutine test2b

0 commit comments

Comments
 (0)