diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -1087,6 +1087,13 @@ tripCount = builder->create(loc, diff2, info.stepValue); } + if (forceLoopToExecuteOnce) { // minimum tripCount is 1 + mlir::Value one = + builder->createIntegerConstant(loc, tripCount.getType(), 1); + auto cond = builder->create( + loc, mlir::arith::CmpIPredicate::slt, tripCount, one); + tripCount = builder->create(loc, cond, one, tripCount); + } info.tripVariable = builder->createTemporary(loc, tripCount.getType()); builder->create(loc, tripCount, info.tripVariable); builder->create(loc, lowerValue, info.loopVariable); diff --git a/flang/test/Lower/always-execute-loop-body.f90 b/flang/test/Lower/always-execute-loop-body.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/always-execute-loop-body.f90 @@ -0,0 +1,19 @@ +! RUN: bbc --always-execute-loop-body --emit-fir %s -o - | FileCheck %s + +! Given the flag `--always-execute-loop-body` the compiler emits an extra +! code to change to tripcount, test tries to verify the extra emitted FIR. + +! CHECK-LABEL: func @_QPsome +subroutine some() + integer :: i + + ! CHECK: [[tripcount:%[0-9]+]] = arith.divsi + ! CHECK: [[one:%c1_i32[_0-9]*]] = arith.constant 1 : i32 + ! CHECK: [[cmp:%[0-9]+]] = arith.cmpi slt, [[tripcount]], [[one]] : i32 + ! CHECK: [[newtripcount:%[0-9]+]] = arith.select [[cmp]], [[one]], [[tripcount]] : i32 + ! CHECK: fir.store [[newtripcount]] to %{{[0-9]+}} : !fir.ref + do i=4,1,1 + stop 2 + end do + return +end