diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp index 7e9f8b5de082..2622e1a2128b 100644 --- a/flang/lib/Lower/PFTBuilder.cpp +++ b/flang/lib/Lower/PFTBuilder.cpp @@ -28,10 +28,6 @@ static llvm::cl::opt clDisableStructuredFir( using namespace Fortran; namespace { -static llvm::cl::opt 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 @@ -1062,12 +1058,6 @@ private: if (bounds->Name().thing.symbol->GetType()->IsNumeric( common::TypeCategory::Real)) eval.isUnstructured = true; // real-valued loop control - } else if (std::get_if( - &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 e7168f394403..09fd5498c018 100644 --- a/flang/test/Lower/OpenMP/target.f90 +++ b/flang/test/Lower/OpenMP/target.f90 @@ -684,12 +684,21 @@ subroutine target_unstructured !CHECK-NO-FPRIV: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "_QFtarget_unstructuredEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK-NO-FPRIV: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QFtarget_unstructuredEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) - !CHECK: ^bb1: + !CHECK: scf.while : () -> () { + !CHECK: %[[I_CUR:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref + !CHECK: %[[J_CUR:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref + !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 + !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 + !CHECK: scf.yield + !CHECK: } 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 6d057ed823c3..6f5dfc7359e3 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 -lower-do-while-to-scf-while %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir %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 5ee6562733da..87d30e24fd3f 100644 --- a/flang/test/Lower/loops.f90 +++ b/flang/test/Lower/loops.f90 @@ -147,12 +147,12 @@ end ! CHECK-LABEL: print_nothing subroutine print_nothing(k1, k2) if (k1 > 0) then - ! CHECK: br [[header:\^bb[0-9]+]] - ! CHECK: [[header]] + ! CHECK: scf.while : () -> () { + ! CHECK: scf.condition do while (k1 > k2) print*, k1, k2 ! no output k2 = k2 + 1 - ! CHECK: br [[header]] + ! CHECK: scf.yield end do end if end diff --git a/flang/test/Lower/mixed_loops.f90 b/flang/test/Lower/mixed_loops.f90 index 11534ae9490d..396726b03087 100644 --- a/flang/test/Lower/mixed_loops.f90 +++ b/flang/test/Lower/mixed_loops.f90 @@ -3,7 +3,6 @@ ! 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"} @@ -12,52 +11,40 @@ 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 : 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 - ! CHECK: fir.store %[[C8]] to %[[I]]#0 : !fir.ref - - ! CHECK: cf.br ^[[HDR1:.*]] - ! CHECK: ^[[HDR1]]: // 2 preds: ^{{.*}}, ^[[EXIT2:.*]] - ! CHECK: %[[T:.*]] = fir.load %[[T_REF]] : !fir.ref - ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 - ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[T]], %[[C0]] : i32 - ! CHECK: cf.cond_br %[[COND]], ^[[BODY1:.*]], ^[[EXIT1:.*]] + ! 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 do i=8,13 - ! CHECK: ^[[BODY1]]: // pred: ^[[HDR1]] ! CHECK: %[[C3:.*]] = arith.constant 3 : i32 ! CHECK: hlfir.assign %[[C3]] to %[[J]]#0 : i32, !fir.ref j=3 - ! CHECK: cf.br ^[[HDR2:.*]] - ! CHECK: ^[[HDR2]]: // 2 preds: ^[[BODY1]], ^[[BODY2:.*]] + ! CHECK: scf.while : () -> () { ! CHECK: %[[JVAL:.*]] = fir.load %[[J]]#0 : !fir.ref ! CHECK: %[[IVAL:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: %[[COND2:.*]] = arith.cmpi slt, %[[JVAL]], %[[IVAL]] : i32 - ! CHECK: cf.cond_br %[[COND2]], ^[[BODY2:.*]], ^[[EXIT2]] + ! CHECK: scf.condition(%[[COND2]]) + ! CHECK: } do { do while (j .lt. i) - ! CHECK: ^[[BODY2]]: // pred: ^[[HDR2]] ! CHECK: %[[C2:.*]] = arith.constant 2 : i32 ! CHECK: %[[JVAL2:.*]] = fir.load %[[J]]#0 : !fir.ref ! CHECK: %[[INC2:.*]] = arith.muli %[[C2]], %[[JVAL2]] : i32 ! CHECK: hlfir.assign %[[INC2]] to %[[J]]#0 : i32, !fir.ref j=j*2 - ! CHECK: cf.br ^[[HDR2]] + ! CHECK: scf.yield end do + ! CHECK: } - ! CHECK: ^[[EXIT2]]: // pred: ^[[HDR2]] - ! CHECK: %[[T2:.*]] = fir.load %[[T_REF]] : !fir.ref - ! CHECK: %[[TDEC:.*]] = arith.subi %[[T2]], {{.*}} : i32 - ! CHECK: fir.store %[[TDEC]] to %[[T_REF]] - ! CHECK: %[[I3:.*]] = fir.load %[[I]]#0 : !fir.ref - ! CHECK: %[[IINC:.*]] = arith.addi %[[I3]], {{.*}} overflow : i32 - ! CHECK: fir.store %[[IINC]] to %[[I]]#0 : !fir.ref - ! CHECK: cf.br ^[[HDR1]] + ! CHECK: %[[STEP_I32:.*]] = fir.convert %[[C1]] : (index) -> i32 + ! CHECK: %[[I_CUR:.*]] = fir.load %[[I]]#0 : !fir.ref + ! CHECK: %[[I_NEXT:.*]] = arith.addi %[[I_CUR]], %[[STEP_I32]] overflow : i32 + ! CHECK: fir.result %[[I_NEXT]] : i32 + ! CHECK: fir.store %[[RES]] to %[[I]]#0 : !fir.ref end do - ! CHECK: ^[[EXIT1]]: // pred: ^[[HDR1]] ! CHECK: %[[IPRINT:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[IPRINT]]) ! CHECK: %[[JPRINT:.*]] = fir.load %[[J]]#0 : !fir.ref @@ -78,19 +65,21 @@ subroutine do_inside_while_loop ! CHECK: hlfir.assign %[[C3]] to %[[J]]#0 : i32, !fir.ref j=3 - ! CHECK: cf.br ^[[HDR1:.*]] - ! CHECK: ^[[HDR1]]: // 2 preds: ^{{.*}}, ^[[BODY1:.*]] + ! CHECK: scf.while : () -> () { ! CHECK: %[[JVAL:.*]] = fir.load %[[J]]#0 : !fir.ref ! CHECK: %[[UL:.*]] = arith.constant 21 : i32 ! CHECK: %[[COND:.*]] = arith.cmpi slt, %[[JVAL]], %[[UL]] : i32 - ! CHECK: cf.cond_br %[[COND]], ^[[BODY1]], ^[[EXIT1:.*]] + ! CHECK: scf.condition(%[[COND]]) + ! CHECK: } do { 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: %{{.*}} = fir.do_loop %{{.*}} = {{.*}} to {{.*}} step {{.*}} iter_args(%[[I_IV:.*]] = {{.*}}) -> (i32) { + ! 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.store %[[I_IV]] to %[[I]]#0 : !fir.ref ! CHECK: %[[C2:.*]] = arith.constant 2 : i32 ! CHECK: %[[J2VAL:.*]] = fir.load %[[J]]#0 : !fir.ref @@ -105,10 +94,10 @@ subroutine do_inside_while_loop ! CHECK: fir.store %{{.*}} to %[[I]]#0 : !fir.ref end do - ! CHECK: cf.br ^[[HDR1]] + ! CHECK: scf.yield end do + ! CHECK: } - ! CHECK: ^[[EXIT1]]: // pred: ^[[HDR1]] ! CHECK: %[[IPRINT:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[IPRINT]]) ! CHECK: %[[JPRINT:.*]] = fir.load %[[J]]#0 : !fir.ref diff --git a/flang/test/Lower/pre-fir-tree02.f90 b/flang/test/Lower/pre-fir-tree02.f90 index d61dc801eea6..01f28f9d5c9a 100644 --- a/flang/test/Lower/pre-fir-tree02.f90 +++ b/flang/test/Lower/pre-fir-tree02.f90 @@ -82,15 +82,15 @@ program test_prog ! CHECK: CaseStmt case default ! Note: label-do-loop are canonicalized into do constructs - ! CHECK: <> - ! CHECK: NonLabelDoStmt + ! CHECK: <> + ! CHECK: [[DO_HDR:[0-9]+]] NonLabelDoStmt -> [[DO_END:[0-9]+]]: do 22 while(l<=k) do 22 while(l<=k) ! CHECK: IfStmt if (p(l)<0.) p(l)=cos(p(l)) - ! CHECK: CallStmt + ! CHECK: [[CALL_ID:[0-9]+]] CallStmt: 22 call incr(l) 22 call incr(l) - ! CHECK: EndDoStmt - ! CHECK: <> + ! CHECK: [[DO_END]] EndDoStmt -> [[DO_HDR]] + ! CHECK: <> ! CHECK: CaseStmt case (100:) ! CHECK: EndSelectStmt diff --git a/flang/test/Lower/while_loop.f90 b/flang/test/Lower/while_loop.f90 index 8114394a3991..d68697e910cf 100644 --- a/flang/test/Lower/while_loop.f90 +++ b/flang/test/Lower/while_loop.f90 @@ -11,23 +11,22 @@ subroutine simple_loop ! CHECK: hlfir.assign %[[C5]] to %[[I]]#0 i = 5 - ! CHECK: cf.br ^[[BB1:.*]] - ! CHECK: ^[[BB1]]: // 2 preds: ^{{.*}}, ^[[BB2:.*]] + ! CHECK: scf.while : () -> () { ! CHECK: %[[IVAL:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[IVAL]], %[[C1]] : i32 - ! CHECK: cf.cond_br %[[COND]], ^[[BB2]], ^[[BB3:.*]] - ! CHECK: ^[[BB2]]: // pred: ^[[BB1]] + ! CHECK: scf.condition(%[[COND]]) + ! CHECK: } do { ! CHECK: %[[IVAL2:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: %[[C2:.*]] = arith.constant 2 : i32 ! CHECK: %[[INC:.*]] = arith.subi %[[IVAL2]], %[[C2]] : i32 ! CHECK: hlfir.assign %[[INC]] to %[[I]]#0 : i32, !fir.ref - ! CHECK: cf.br ^[[BB1]] + ! CHECK: scf.yield + ! CHECK: } do while (i .gt. 1) i = i - 2 end do - ! CHECK: ^[[BB3]]: // pred: ^[[BB1]] ! CHECK: %[[IVAL3:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[IVAL3]]) print *, i @@ -46,14 +45,13 @@ subroutine while_inside_while_loop ! CHECK: hlfir.assign %[[C13]] to %[[I]]#0 i = 13 - ! CHECK: cf.br ^[[HDR1:.*]] - ! CHECK: ^[[HDR1]]: // 2 preds: ^{{.*}}, ^[[EXIT2:.*]] + ! CHECK: scf.while : () -> () { ! CHECK: %[[IVAL:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: %[[C8:.*]] = arith.constant 8 : i32 ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[IVAL]], %[[C8]] : i32 - ! CHECK: cf.cond_br %[[COND]], ^[[BODY1:.*]], ^[[EXIT1:.*]] + ! CHECK: scf.condition(%[[COND]]) + ! CHECK: } do { do while (i .gt. 8) - ! CHECK: ^[[BODY1]]: // pred: ^[[HDR1]] ! CHECK: %[[IVAL2:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: %[[C5:.*]] = arith.constant 5 : i32 ! CHECK: %[[INC:.*]] = arith.subi %[[IVAL2]], %[[C5]] : i32 @@ -64,27 +62,26 @@ subroutine while_inside_while_loop ! CHECK: hlfir.assign %[[C3]] to %[[J]]#0 j = 3 - ! CHECK: cf.br ^[[HDR2:.*]] - ! CHECK: ^[[HDR2]]: // 2 preds: ^[[BODY1]], ^[[BODY2:.*]] + ! CHECK: scf.while : () -> () { ! CHECK: %[[JVAL:.*]] = fir.load %[[J]]#0 : !fir.ref ! CHECK: %[[IVAL3:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: %[[COND2:.*]] = arith.cmpi slt, %[[JVAL]], %[[IVAL3]] : i32 - ! CHECK: cf.cond_br %[[COND2]], ^[[BODY2]], ^[[EXIT2:.*]] + ! CHECK: scf.condition(%[[COND2]]) + ! CHECK: } do { do while (j .lt. i) - ! CHECK: ^[[BODY2]]: // pred: ^[[HDR2]] ! CHECK: %[[C2:.*]] = arith.constant 2 : i32 ! CHECK: %[[JVAL2:.*]] = fir.load %[[J]]#0 : !fir.ref ! CHECK: %[[INC2:.*]] = arith.muli %[[C2]], %[[JVAL2]] : i32 ! CHECK: hlfir.assign %[[INC2]] to %[[J]]#0 : i32, !fir.ref j = j * 2 - ! CHECK: cf.br ^[[HDR2]] + ! CHECK: scf.yield end do + ! CHECK: } - ! CHECK: ^[[EXIT2]]: // pred: ^[[HDR2]] - ! CHECK: cf.br ^[[HDR1]] + ! CHECK: scf.yield end do + ! CHECK: } - ! CHECK: ^[[EXIT1]]: // pred: ^[[HDR1]] ! CHECK: %[[IPRINT:.*]] = fir.load %[[I]]#0 : !fir.ref ! CHECK: fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[IPRINT]]) ! CHECK: %[[JPRINT:.*]] = fir.load %[[J]]#0 : !fir.ref