[llvm-branch-commits] [flang] b2a6530 - Revert "[flang] make lowering to scf.while default (#184234)"

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Mar 4 03:23:59 PST 2026


Author: jeanPerier
Date: 2026-03-04T12:23:55+01:00
New Revision: b2a65301d9923031edd35f2d7c70470ef5bf42fc

URL: https://github.com/llvm/llvm-project/commit/b2a65301d9923031edd35f2d7c70470ef5bf42fc
DIFF: https://github.com/llvm/llvm-project/commit/b2a65301d9923031edd35f2d7c70470ef5bf42fc.diff

LOG: Revert "[flang] make lowering to scf.while default (#184234)"

This reverts commit 62144f48d43fc33d7e73fff68aea31dd287d5349.

Added: 
    

Modified: 
    flang/lib/Lower/PFTBuilder.cpp
    flang/test/Lower/OpenMP/target.f90
    flang/test/Lower/do-while-to-scf-while.f90
    flang/test/Lower/loops.f90
    flang/test/Lower/mixed_loops.f90
    flang/test/Lower/pre-fir-tree02.f90
    flang/test/Lower/while_loop.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index 2622e1a2128b4..7e9f8b5de0827 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -28,6 +28,10 @@ static llvm::cl::opt<bool> clDisableStructuredFir(
 using namespace Fortran;
 
 namespace {
+static llvm::cl::opt<bool> lowerDoWhileToSCFWhile(
+    "lower-do-while-to-scf-while", llvm::cl::init(false),
+    llvm::cl::desc("lower structured DO WHILE loops to scf.while"),
+    llvm::cl::Hidden);
 /// Helpers to unveil parser node inside Fortran::parser::Statement<>,
 /// Fortran::parser::UnlabeledStatement, and Fortran::common::Indirection<>
 template <typename A>
@@ -1058,6 +1062,12 @@ class PFTBuilder {
               if (bounds->Name().thing.symbol->GetType()->IsNumeric(
                       common::TypeCategory::Real))
                 eval.isUnstructured = true; // real-valued loop control
+            } else if (std::get_if<parser::ScalarLogicalExpr>(
+                           &loopControl->u)) {
+              // Leave DO WHILE structured when -lower-do-while-to-scf-while is
+              // enabled; branch analysis will mark unstructured cases.
+              if (!lowerDoWhileToSCFWhile)
+                eval.isUnstructured = true; // while loop
             }
           },
           [&](const parser::EndDoStmt &) {

diff  --git a/flang/test/Lower/OpenMP/target.f90 b/flang/test/Lower/OpenMP/target.f90
index 09fd5498c018a..e7168f3944037 100644
--- a/flang/test/Lower/OpenMP/target.f90
+++ b/flang/test/Lower/OpenMP/target.f90
@@ -684,21 +684,12 @@ subroutine target_unstructured
       !CHECK-NO-FPRIV: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "_QFtarget_unstructuredEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
       !CHECK-NO-FPRIV: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QFtarget_unstructuredEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
 
-      !CHECK: scf.while : () -> () {
-      !CHECK:   %[[I_CUR:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32>
-      !CHECK:   %[[J_CUR:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i32>
-      !CHECK:   %[[COND:.*]] = arith.cmpi sle, %[[I_CUR]], %[[J_CUR]] : i32
-      !CHECK:   scf.condition(%[[COND]])
-      !CHECK: } do {
-      !CHECK:   %[[I_BODY:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32>
-      !CHECK:   %[[ONE:.*]] = arith.constant 1 : i32
-      !CHECK:   %[[I_NEXT:.*]] = arith.addi %[[I_BODY]], %[[ONE]] : i32
-      !CHECK:   hlfir.assign %[[I_NEXT]] to %[[VAL_8]]#0 : i32, !fir.ref<i32>
-      !CHECK:   scf.yield
-      !CHECK: }
+      !CHECK: ^bb1:
       do while (i <= j)
+         !CHECK: ^bb2:
          i = i + 1
       end do
+      !CHECK: ^bb3:
       !CHECK: omp.terminator
    !$omp end target
    !CHECK: }

diff  --git a/flang/test/Lower/do-while-to-scf-while.f90 b/flang/test/Lower/do-while-to-scf-while.f90
index 6f5dfc7359e37..6d057ed823c36 100644
--- a/flang/test/Lower/do-while-to-scf-while.f90
+++ b/flang/test/Lower/do-while-to-scf-while.f90
@@ -1,4 +1,4 @@
-! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
+! RUN: bbc -emit-hlfir -lower-do-while-to-scf-while %s -o - | FileCheck %s
 
 ! CHECK-LABEL: func.func @_QPsimple_do_while()
 ! CHECK: scf.while

diff  --git a/flang/test/Lower/loops.f90 b/flang/test/Lower/loops.f90
index 87d30e24fd3f7..5ee6562733dae 100644
--- a/flang/test/Lower/loops.f90
+++ b/flang/test/Lower/loops.f90
@@ -147,12 +147,12 @@ subroutine lis(n)
 ! CHECK-LABEL: print_nothing
 subroutine print_nothing(k1, k2)
   if (k1 > 0) then
-    ! CHECK: scf.while : () -> () {
-    ! CHECK: scf.condition
+    ! CHECK: br [[header:\^bb[0-9]+]]
+    ! CHECK: [[header]]
     do while (k1 > k2)
       print*, k1, k2 ! no output
       k2 = k2 + 1
-      ! CHECK: scf.yield
+      ! CHECK: br [[header]]
     end do
   end if
 end

diff  --git a/flang/test/Lower/mixed_loops.f90 b/flang/test/Lower/mixed_loops.f90
index 396726b030875..11534ae9490d0 100644
--- a/flang/test/Lower/mixed_loops.f90
+++ b/flang/test/Lower/mixed_loops.f90
@@ -3,6 +3,7 @@
 ! Test while loop inside do loop.
 ! CHECK-LABEL: while_inside_do_loop
 subroutine while_inside_do_loop
+  ! CHECK-DAG: %[[T_REF:.*]] = fir.alloca i32
   ! CHECK-DAG: %[[I_ADDR:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFwhile_inside_do_loopEi"}
   ! CHECK-DAG: %[[I:.*]]:2 = hlfir.declare %[[I_ADDR]]
   ! CHECK-DAG: %[[J_ADDR:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFwhile_inside_do_loopEj"}
@@ -11,40 +12,52 @@ subroutine while_inside_do_loop
 
   ! CHECK-DAG: %[[C8:.*]] = arith.constant 8 : i32
   ! CHECK-DAG: %[[C13:.*]] = arith.constant 13 : i32
-  ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index
-  ! CHECK-DAG: %[[LB:.*]] = fir.convert %[[C8]] : (i32) -> index
-  ! CHECK-DAG: %[[UB:.*]] = fir.convert %[[C13]] : (i32) -> index
-  ! CHECK-DAG: %[[INIT:.*]] = fir.convert %[[LB]] : (index) -> i32
-  ! CHECK: %[[RES:.*]] = fir.do_loop %{{.*}} = %[[LB]] to %[[UB]] step %[[C1]] iter_args(%[[I_IV:.*]] = %[[INIT]]) -> (i32) {
-  ! CHECK:   fir.store %[[I_IV]] to %[[I]]#0 : !fir.ref<i32>
+  ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32
+  ! CHECK: %[[DIFF:.*]] = arith.subi %[[C13]], %[[C8]] : i32
+  ! CHECK: %[[RANGE:.*]] = arith.addi %[[DIFF]], %[[C1]] : i32
+  ! CHECK: %[[HIGH:.*]] = arith.divsi %[[RANGE]], %[[C1]] : i32
+  ! CHECK: fir.store %[[HIGH]] to %[[T_REF]] : !fir.ref<i32>
+  ! CHECK: fir.store %[[C8]] to %[[I]]#0 : !fir.ref<i32>
+
+  ! CHECK: cf.br ^[[HDR1:.*]]
+  ! CHECK: ^[[HDR1]]:  // 2 preds: ^{{.*}}, ^[[EXIT2:.*]]
+  ! CHECK: %[[T:.*]] = fir.load %[[T_REF]] : !fir.ref<i32>
+  ! CHECK: %[[C0:.*]] = arith.constant 0 : i32
+  ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[T]], %[[C0]] : i32
+  ! CHECK: cf.cond_br %[[COND]], ^[[BODY1:.*]], ^[[EXIT1:.*]]
   do i=8,13
+    ! CHECK: ^[[BODY1]]:  // pred: ^[[HDR1]]
     ! CHECK: %[[C3:.*]] = arith.constant 3 : i32
     ! CHECK: hlfir.assign %[[C3]] to %[[J]]#0 : i32, !fir.ref<i32>
     j=3
 
-    ! CHECK: scf.while : () -> () {
+    ! CHECK: cf.br ^[[HDR2:.*]]
+    ! CHECK: ^[[HDR2]]:  // 2 preds: ^[[BODY1]], ^[[BODY2:.*]]
     ! CHECK: %[[JVAL:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
     ! CHECK: %[[IVAL:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
     ! CHECK: %[[COND2:.*]] = arith.cmpi slt, %[[JVAL]], %[[IVAL]] : i32
-    ! CHECK: scf.condition(%[[COND2]])
-    ! CHECK: } do {
+    ! CHECK: cf.cond_br %[[COND2]], ^[[BODY2:.*]], ^[[EXIT2]]
     do while (j .lt. i)
+      ! CHECK: ^[[BODY2]]:  // pred: ^[[HDR2]]
       ! CHECK: %[[C2:.*]] = arith.constant 2 : i32
       ! CHECK: %[[JVAL2:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
       ! CHECK: %[[INC2:.*]] = arith.muli %[[C2]], %[[JVAL2]] : i32
       ! CHECK: hlfir.assign %[[INC2]] to %[[J]]#0 : i32, !fir.ref<i32>
       j=j*2
-    ! CHECK: scf.yield
+    ! CHECK: cf.br ^[[HDR2]]
     end do
-    ! CHECK: }
 
-  ! CHECK: %[[STEP_I32:.*]] = fir.convert %[[C1]] : (index) -> i32
-  ! CHECK: %[[I_CUR:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
-  ! CHECK: %[[I_NEXT:.*]] = arith.addi %[[I_CUR]], %[[STEP_I32]] overflow<nsw> : i32
-  ! CHECK: fir.result %[[I_NEXT]] : i32
-  ! CHECK: fir.store %[[RES]] to %[[I]]#0 : !fir.ref<i32>
+  ! CHECK: ^[[EXIT2]]: // pred: ^[[HDR2]]
+  ! CHECK: %[[T2:.*]] = fir.load %[[T_REF]] : !fir.ref<i32>
+  ! CHECK: %[[TDEC:.*]] = arith.subi %[[T2]], {{.*}} : i32
+  ! CHECK: fir.store %[[TDEC]] to %[[T_REF]]
+  ! CHECK: %[[I3:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
+  ! CHECK: %[[IINC:.*]] = arith.addi %[[I3]], {{.*}} overflow<nsw> : i32
+  ! CHECK: fir.store %[[IINC]] to %[[I]]#0 : !fir.ref<i32>
+  ! CHECK: cf.br ^[[HDR1]]
   end do
 
+  ! CHECK: ^[[EXIT1]]:  // pred: ^[[HDR1]]
   ! CHECK: %[[IPRINT:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
   ! CHECK: fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[IPRINT]])
   ! CHECK: %[[JPRINT:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
@@ -65,21 +78,19 @@ subroutine do_inside_while_loop
     ! CHECK: hlfir.assign %[[C3]] to %[[J]]#0 : i32, !fir.ref<i32>
     j=3
 
-    ! CHECK: scf.while : () -> () {
+    ! CHECK: cf.br ^[[HDR1:.*]]
+    ! CHECK: ^[[HDR1]]:  // 2 preds: ^{{.*}}, ^[[BODY1:.*]]
     ! CHECK: %[[JVAL:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
     ! CHECK: %[[UL:.*]] = arith.constant 21 : i32
     ! CHECK: %[[COND:.*]] = arith.cmpi slt, %[[JVAL]], %[[UL]] : i32
-    ! CHECK: scf.condition(%[[COND]])
-    ! CHECK: } do {
+    ! CHECK: cf.cond_br %[[COND]], ^[[BODY1]], ^[[EXIT1:.*]]
     do while (j .lt. 21)
+      ! CHECK: ^[[BODY1]]:  // pred: ^[[HDR1]]
 
       ! CHECK-DAG: %[[C8:.*]] = arith.constant 8 : i32
       ! CHECK-DAG: %[[C13:.*]] = arith.constant 13 : i32
       ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index
-      ! CHECK-DAG: %[[LB:.*]] = fir.convert %[[C8]] : (i32) -> index
-      ! CHECK-DAG: %[[UB:.*]] = fir.convert %[[C13]] : (i32) -> index
-      ! CHECK-DAG: %[[INIT:.*]] = fir.convert %[[LB]] : (index) -> i32
-      ! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %[[LB]] to %[[UB]] step %[[C1]] iter_args(%[[I_IV:.*]] = %[[INIT]]) -> (i32) {
+      ! CHECK: %{{.*}} = fir.do_loop %{{.*}} = {{.*}} to {{.*}} step {{.*}} iter_args(%[[I_IV:.*]] = {{.*}}) -> (i32) {
         ! CHECK: fir.store %[[I_IV]] to %[[I]]#0 : !fir.ref<i32>
         ! CHECK: %[[C2:.*]] = arith.constant 2 : i32
         ! CHECK: %[[J2VAL:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
@@ -94,10 +105,10 @@ subroutine do_inside_while_loop
       ! CHECK: fir.store %{{.*}} to %[[I]]#0 : !fir.ref<i32>
       end do
 
-    ! CHECK: scf.yield
+    ! CHECK: cf.br ^[[HDR1]]
     end do
-  ! CHECK: }
 
+  ! CHECK: ^[[EXIT1]]:  // pred: ^[[HDR1]]
   ! CHECK: %[[IPRINT:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
   ! CHECK: fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[IPRINT]])
   ! CHECK: %[[JPRINT:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>

diff  --git a/flang/test/Lower/pre-fir-tree02.f90 b/flang/test/Lower/pre-fir-tree02.f90
index 01f28f9d5c9aa..d61dc801eea60 100644
--- a/flang/test/Lower/pre-fir-tree02.f90
+++ b/flang/test/Lower/pre-fir-tree02.f90
@@ -82,15 +82,15 @@ subroutine incr(i)
       ! CHECK: CaseStmt
       case default
         ! Note: label-do-loop are canonicalized into do constructs
-        ! CHECK: <<DoConstruct>>
-        ! CHECK: [[DO_HDR:[0-9]+]] NonLabelDoStmt -> [[DO_END:[0-9]+]]: do 22 while(l<=k)
+        ! CHECK: <<DoConstruct!>>
+        ! CHECK: NonLabelDoStmt
         do 22 while(l<=k)
           ! CHECK: IfStmt
           if (p(l)<0.) p(l)=cos(p(l))
-          ! CHECK: [[CALL_ID:[0-9]+]] CallStmt: 22 call incr(l)
+          ! CHECK: CallStmt
 22        call incr(l)
-        ! CHECK: [[DO_END]] EndDoStmt -> [[DO_HDR]]
-       ! CHECK: <<End DoConstruct>>
+        ! CHECK: EndDoStmt
+       ! CHECK: <<End DoConstruct!>>
       ! CHECK: CaseStmt
       case (100:)
     ! CHECK: EndSelectStmt

diff  --git a/flang/test/Lower/while_loop.f90 b/flang/test/Lower/while_loop.f90
index d68697e910cf0..8114394a39919 100644
--- a/flang/test/Lower/while_loop.f90
+++ b/flang/test/Lower/while_loop.f90
@@ -11,22 +11,23 @@ subroutine simple_loop
   ! CHECK: hlfir.assign %[[C5]] to %[[I]]#0
   i = 5
 
-  ! CHECK: scf.while : () -> () {
+  ! CHECK: cf.br ^[[BB1:.*]]
+  ! CHECK: ^[[BB1]]:  // 2 preds: ^{{.*}}, ^[[BB2:.*]]
   ! CHECK: %[[IVAL:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
   ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
   ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[IVAL]], %[[C1]] : i32
-  ! CHECK: scf.condition(%[[COND]])
-  ! CHECK: } do {
+  ! CHECK: cf.cond_br %[[COND]], ^[[BB2]], ^[[BB3:.*]]
+  ! CHECK: ^[[BB2]]:  // pred: ^[[BB1]]
   ! CHECK: %[[IVAL2:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
   ! CHECK: %[[C2:.*]] = arith.constant 2 : i32
   ! CHECK: %[[INC:.*]] = arith.subi %[[IVAL2]], %[[C2]] : i32
   ! CHECK: hlfir.assign %[[INC]] to %[[I]]#0 : i32, !fir.ref<i32>
-  ! CHECK: scf.yield
-  ! CHECK: }
+  ! CHECK: cf.br ^[[BB1]]
   do while (i .gt. 1)
     i = i - 2
   end do
 
+  ! CHECK: ^[[BB3]]:  // pred: ^[[BB1]]
   ! CHECK: %[[IVAL3:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
   ! CHECK: fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[IVAL3]])
   print *, i
@@ -45,13 +46,14 @@ subroutine while_inside_while_loop
   ! CHECK: hlfir.assign %[[C13]] to %[[I]]#0
   i = 13
 
-  ! CHECK: scf.while : () -> () {
+  ! CHECK: cf.br ^[[HDR1:.*]]
+  ! CHECK: ^[[HDR1]]:  // 2 preds: ^{{.*}}, ^[[EXIT2:.*]]
   ! CHECK: %[[IVAL:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
   ! CHECK: %[[C8:.*]] = arith.constant 8 : i32
   ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[IVAL]], %[[C8]] : i32
-  ! CHECK: scf.condition(%[[COND]])
-  ! CHECK: } do {
+  ! CHECK: cf.cond_br %[[COND]], ^[[BODY1:.*]], ^[[EXIT1:.*]]
   do while (i .gt. 8)
+    ! CHECK: ^[[BODY1]]:  // pred: ^[[HDR1]]
     ! CHECK: %[[IVAL2:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
     ! CHECK: %[[C5:.*]] = arith.constant 5 : i32
     ! CHECK: %[[INC:.*]] = arith.subi %[[IVAL2]], %[[C5]] : i32
@@ -62,26 +64,27 @@ subroutine while_inside_while_loop
     ! CHECK: hlfir.assign %[[C3]] to %[[J]]#0
     j = 3
 
-    ! CHECK: scf.while : () -> () {
+    ! CHECK: cf.br ^[[HDR2:.*]]
+    ! CHECK: ^[[HDR2]]:  // 2 preds: ^[[BODY1]], ^[[BODY2:.*]]
     ! CHECK: %[[JVAL:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
     ! CHECK: %[[IVAL3:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
     ! CHECK: %[[COND2:.*]] = arith.cmpi slt, %[[JVAL]], %[[IVAL3]] : i32
-    ! CHECK: scf.condition(%[[COND2]])
-    ! CHECK: } do {
+    ! CHECK: cf.cond_br %[[COND2]], ^[[BODY2]], ^[[EXIT2:.*]]
     do while (j .lt. i)
+      ! CHECK: ^[[BODY2]]:  // pred: ^[[HDR2]]
       ! CHECK: %[[C2:.*]] = arith.constant 2 : i32
       ! CHECK: %[[JVAL2:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
       ! CHECK: %[[INC2:.*]] = arith.muli %[[C2]], %[[JVAL2]] : i32
       ! CHECK: hlfir.assign %[[INC2]] to %[[J]]#0 : i32, !fir.ref<i32>
       j = j * 2
-    ! CHECK: scf.yield
+    ! CHECK: cf.br ^[[HDR2]]
     end do
-    ! CHECK: }
 
-    ! CHECK: scf.yield
+    ! CHECK: ^[[EXIT2]]: // pred: ^[[HDR2]]
+    ! CHECK: cf.br ^[[HDR1]]
   end do
-  ! CHECK: }
 
+  ! CHECK: ^[[EXIT1]]:  // pred: ^[[HDR1]]
   ! CHECK: %[[IPRINT:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
   ! CHECK: fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[IPRINT]])
   ! CHECK: %[[JPRINT:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>


        


More information about the llvm-branch-commits mailing list