-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang][Lower] Treat directives with nested evaluations as constructs #91614
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When generating block terminators in `genFIR(Evaluation)`, treat `Directives` with nested evaluations the same way as `Constructs` to determine the successor block. This fixes llvm#91526
@llvm/pr-subscribers-flang-fir-hlfir Author: Krzysztof Parzyszek (kparzysz) ChangesWhen generating block terminators in This fixes #91526 Full diff: https://github.com/llvm/llvm-project/pull/91614.diff 2 Files Affected:
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 4902886712e92..79d6bbf65cbf7 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -4548,9 +4548,13 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// constructs, this can be done for either the end construct statement,
// or for the construct itself, which will skip this code if the
// end statement was visited first and generated a branch.
- Fortran::lower::pft::Evaluation *successor =
- eval.isConstruct() ? eval.getLastNestedEvaluation().lexicalSuccessor
- : eval.lexicalSuccessor;
+ Fortran::lower::pft::Evaluation *successor = [&]() {
+ if (eval.isConstruct() ||
+ (eval.isDirective() && eval.hasNestedEvaluations()))
+ return eval.getLastNestedEvaluation().lexicalSuccessor;
+ return eval.lexicalSuccessor;
+ }();
+
if (successor && blockIsUnterminated()) {
if (successor->isIntermediateConstructStmt() &&
successor->parentConstruct->lowerAsUnstructured())
diff --git a/flang/test/Lower/branching-directive.f90 b/flang/test/Lower/branching-directive.f90
new file mode 100644
index 0000000000000..a0a147f1053a4
--- /dev/null
+++ b/flang/test/Lower/branching-directive.f90
@@ -0,0 +1,25 @@
+!RUN: flang-new -fc1 -emit-hlfir -fopenmp -o - %s | FileCheck %s
+
+!https://github.com/llvm/llvm-project/issues/91526
+
+!CHECK: cf.cond_br %{{[0-9]+}}, ^bb[[THEN:[0-9]+]], ^bb[[ELSE:[0-9]+]]
+!CHECK: ^bb[[THEN]]:
+!CHECK: cf.br ^bb[[EXIT:[0-9]+]]
+!CHECK: ^bb[[ELSE]]:
+!CHECK: fir.call @_FortranAStopStatement
+!CHECK: fir.unreachable
+!CHECK: ^bb[[EXIT]]:
+
+subroutine simple(y)
+ implicit none
+ logical, intent(in) :: y
+ integer :: i
+ if (y) then
+!$omp parallel
+ i = 1
+!$omp end parallel
+ else
+ stop 1
+ end if
+end subroutine simple
+
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks ok to me - thanks for the fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kparzysz for fixing this quickly. My minor concern was whether this is only an isolated issue or whether there could be similar issues elsewhere that warrants a general solution. But since Val has approved, it is probably alrite.
If you could wait till tomorrow, @Leporacanthicus can check this on the application that hit the issue.
I don't have the context for this PR. But if any OpenMP or other directive appears immediately before a CASE statement,or before an ELSE statement in an unstructured context, to give two examples, then this fix will be needed. Ah yes! Chasing the issue link, there is an OpenMP directive followed by an ELSE statement in an unstructured context! |
I think this fix is doing something good - it helps in SOME cases, but perhaps not "good enough". I'm not opposed to this going in... But a complete fix would be better, in my (and Kiran's) opinion. It doesn't fix my original problem, I'm still seeing the STOP when it shouldn't for this code:
Compiler generates this MLIR (only the "interesting portion" shown here):
Not sure if it's because the parallel section has a do and/or a reduction inside it? |
Yeah, this patch doesn't really fix the problem... I think we may need to revamp the block/branch generation. What I'm thinking is to generate empty blocks and linking (unconditional) branches early, and then fill them out in It seems to me like that should work, but maybe there are some special cases that would cause complications. What do you think? |
Yes, that sounds like it would work. I've spent a little bit of time today trying to come up with some easy fix, but that just led to a few hundred tests failing - and didn't really fix the issue either... :) |
The current implementation presented here resolves an issue I ran into:
The first iteration here, even if not perfect, is usable for some cases. I support the conversation on a more complete solution though - and seems to me that it can be done even if this first implementation is merged :) Thank you for looking into this! |
Agree. If it helps a known case this can go in and we can fix the general issue separately. |
Yes, this fix is necessary and useful. Please push. |
When lowering IfConstruct, CaseConstruct, and SelectTypeConstruct, emit branches that exit the construct in each block that is still unterminated after the FIR has been generated in it. The same thing may be needed for SelectRankConstruct, once it's supported. This eliminates the need for inserting branches in `genFIR(Evaluation)`. Follow-up to PR llvm#91614.
When lowering IfConstruct, CaseConstruct, and SelectTypeConstruct, emit branches that exit the construct in each block that is still unterminated after the FIR has been generated in it. The same thing may be needed for SelectRankConstruct, once it's supported. This eliminates the need for inserting branches in `genFIR(Evaluation)`. Follow-up to PR #91614.
When generating block terminators in
genFIR(Evaluation)
, treatDirectives
with nested evaluations the same way asConstructs
to determine the successor block.This fixes #91526