Revert "[flang] make lowering to scf.while default" (#184592)
Reverts llvm/llvm-project#184234
This is breaking SPEC and other tests.
Reproducer:
```
subroutine foo()
logical :: l1, l2
do while (l1())
if (l2()) then
call bar()
endif
enddo
end
```
The cause is a pass ordering issue between the SCFToControlFlowPass and
CfgConversionPass
[here](d0f50d5574/flang/lib/Optimizer/Passes/Pipelines.cpp (L239-L240)).
I think they need to be run simultaneously somehow because the both SCF
and FIR structured operations may contain each other, and none will be
happy to get block CFG generated inside their region by the pass
lowering the other.
Reverting while this is sorted out.
This commit is contained in:
parent
9c2829f2e1
commit
ee8184573f
@ -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 @@ private:
|
||||
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 &) {
|
||||
|
||||
@ -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: }
|
||||
|
||||
@ -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
|
||||
|
||||
@ -147,12 +147,12 @@ end
|
||||
! 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
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -82,15 +82,15 @@ program test_prog
|
||||
! 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
|
||||
|
||||
@ -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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user