[flang-commits] [flang] 16d2bcd - [flang][lower] fix source location in WHERE constructs (#194849)
via flang-commits
flang-commits at lists.llvm.org
Thu Apr 30 00:21:49 PDT 2026
Author: jeanPerier
Date: 2026-04-30T09:21:43+02:00
New Revision: 16d2bcd5a8cc76aa97639da150467d20be343331
URL: https://github.com/llvm/llvm-project/commit/16d2bcd5a8cc76aa97639da150467d20be343331
DIFF: https://github.com/llvm/llvm-project/commit/16d2bcd5a8cc76aa97639da150467d20be343331.diff
LOG: [flang][lower] fix source location in WHERE constructs (#194849)
The location of hlfir.where operations was not set correctly (left to
the location of the previous statement of construct).
Fix this and add test.
While doing so, I noticed the bridge current location was not set
consistently when entering constructs. While this usually was OK because
no code was emitting in many case before visiting an inner construct,
there was at least one case where this lead to bad location for OpenAcc
atomic. Hence I updated all construct that did not call
`setCurrentPositionAt` to do it, this seems more future proof.
Added:
flang/test/Lower/where-loc.f90
Modified:
flang/lib/Lower/Bridge.cpp
flang/test/Lower/OpenACC/locations.f90
flang/test/Lower/OpenMP/location.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index cf9da627c19f1..c5709e1cd94d4 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -3435,6 +3435,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
/// Generate FIR for a FORALL construct.
void genFIR(const Fortran::parser::ForallConstruct &forall) {
+ setCurrentPositionAt(forall);
mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint();
if (lowerToHighLevelFIR())
localSymbols.pushScope();
@@ -3668,6 +3669,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
void genFIR(const Fortran::parser::OpenACCConstruct &acc) {
+ setCurrentPositionAt(acc);
Fortran::lower::clearCollapsedDoConstructs();
mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint();
@@ -3830,6 +3832,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
void genFIR(const Fortran::parser::OpenACCDeclarativeConstruct &accDecl) {
+ setCurrentPositionAt(accDecl);
genOpenACCDeclarativeConstruct(*this, bridge.getSemanticsContext(),
bridge.openAccCtx(), accDecl);
for (Fortran::lower::pft::Evaluation &e : getEval().getNestedEvaluations())
@@ -3841,6 +3844,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
void genFIR(const Fortran::parser::CUFKernelDoConstruct &kernel) {
+ setCurrentPositionAt(kernel);
Fortran::lower::SymMapScope scope(localSymbols);
const Fortran::parser::CUFKernelDoConstruct::Directive &dir =
std::get<Fortran::parser::CUFKernelDoConstruct::Directive>(kernel.t);
@@ -4112,6 +4116,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
void genFIR(const Fortran::parser::OpenMPConstruct &omp) {
+ setCurrentPositionAt(omp);
mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint();
genOpenMPConstruct(*this, localSymbols, bridge.getSemanticsContext(),
getEval(), omp);
@@ -4123,6 +4128,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
void genFIR(const Fortran::parser::OpenMPDeclarativeConstruct &ompDecl) {
+ setCurrentPositionAt(ompDecl);
mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint();
// Register if a declare target construct intended for a target device was
// found
@@ -4379,6 +4385,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
void genFIR(const Fortran::parser::ChangeTeamConstruct &construct) {
+ setCurrentPositionAt(construct);
Fortran::lower::StatementContext stmtCtx;
pushActiveConstruct(getEval(), stmtCtx);
Fortran::lower::pft::Evaluation &eval = getEval();
@@ -6076,6 +6083,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
bool isInsideHlfirWhere() const { return isInsideOp<hlfir::WhereOp>(); }
void genFIR(const Fortran::parser::WhereConstruct &c) {
+ setCurrentPositionAt(c);
mlir::Location loc = getCurrentLocation();
hlfir::WhereOp whereOp;
@@ -6157,6 +6165,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
implicitIterSpace.append(maskExpr);
}
void genFIR(const Fortran::parser::WhereConstruct::MaskedElsewhere &ew) {
+ setCurrentPositionAt(ew);
mlir::Location loc = getCurrentLocation();
hlfir::ElseWhereOp elsewhereOp;
if (lowerToHighLevelFIR()) {
@@ -6186,6 +6195,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
implicitIterSpace.append(maskExpr);
}
void genFIR(const Fortran::parser::WhereConstruct::Elsewhere &ew) {
+ setCurrentPositionAt(ew);
if (lowerToHighLevelFIR()) {
auto elsewhereOp =
hlfir::ElseWhereOp::create(*builder, getCurrentLocation());
diff --git a/flang/test/Lower/OpenACC/locations.f90 b/flang/test/Lower/OpenACC/locations.f90
index 8e00721ba2b4d..46e8df0e9dac4 100644
--- a/flang/test/Lower/OpenACC/locations.f90
+++ b/flang/test/Lower/OpenACC/locations.f90
@@ -146,8 +146,8 @@ subroutine atomic_update_loc()
!$acc atomic
y = y + 1
! CHECK: acc.atomic.update %{{.*}} : !fir.ref<i32> {
-! CHECK: ^bb0(%{{.*}}: i32 loc("{{.*}}locations.f90":142:3)):
-! CHECK: } loc("{{.*}}locations.f90":142:3)
+! CHECK: ^bb0(%{{.*}}: i32 loc("{{.*}}locations.f90":146:11)):
+! CHECK: } loc("{{.*}}locations.f90":146:11)
!$acc atomic update
z = x * z
diff --git a/flang/test/Lower/OpenMP/location.f90 b/flang/test/Lower/OpenMP/location.f90
index fc7dd43499863..7d55c10959727 100644
--- a/flang/test/Lower/OpenMP/location.f90
+++ b/flang/test/Lower/OpenMP/location.f90
@@ -66,5 +66,5 @@ subroutine sub_if(c)
!CHECK: #[[BAR_LOC]] = loc("{{.*}}location.f90":46:9)
!CHECK: #[[TW_LOC]] = loc("{{.*}}location.f90":48:9)
!CHECK: #[[TY_LOC]] = loc("{{.*}}location.f90":50:9)
-!CHECK: #[[IF_LOC]] = loc("{{.*}}location.f90":57:14)
!CHECK: #[[TASK_LOC]] = loc("{{.*}}location.f90":57:9)
+!CHECK: #[[IF_LOC]] = loc("{{.*}}location.f90":57:14)
diff --git a/flang/test/Lower/where-loc.f90 b/flang/test/Lower/where-loc.f90
new file mode 100644
index 0000000000000..75d1452da9df2
--- /dev/null
+++ b/flang/test/Lower/where-loc.f90
@@ -0,0 +1,38 @@
+! Test line location lowering of WHERE statements.
+! RUN: %flang -fc1 -emit-hlfir -mmlir -mlir-print-debuginfo -mmlir --mlir-print-local-scope -o - %s | FileCheck %s
+
+! CHECK-LABEL: func.func @_QPtest_where_construct
+subroutine test_where_construct(mask, m2, x, y)
+ logical :: mask(10), m2(10)
+ real :: x(10), y(10)
+ x = 0.0
+ ! Closing braces of hlfir.where / hlfir.elsewhere appear in reverse
+ ! nesting order in the printed IR. The first closing brace is the
+ ! innermost ELSEWHERE, then ELSEWHERE(m2), then WHERE.
+
+ ! CHECK: hlfir.elsewhere do
+ ! CHECK: hlfir.yield
+ ! CHECK: hlfir.yield
+ where (mask)
+ x = y
+ elsewhere (m2)
+ x = -y
+ elsewhere
+ x = 1.0
+ end where
+ ! CHECK: } loc("{{.*}}where-loc.f90":[[# @LINE-3]]:
+ ! CHECK: } loc("{{.*}}where-loc.f90":[[# @LINE-6]]:
+ ! CHECK: } loc("{{.*}}where-loc.f90":[[# @LINE-9]]:
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_where_stmt
+subroutine test_where_stmt(mask, x, y)
+ logical :: mask(10)
+ real :: x(10), y(10)
+ ! Prior statement.
+ x = 0.0
+ ! CHECK: hlfir.yield
+ ! CHECK: hlfir.yield
+ where (mask) x = y
+ ! CHECK: } loc("{{.*}}where-loc.f90":[[# @LINE-1]]:
+end subroutine
More information about the flang-commits
mailing list