Skip to content
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

[Clang][OpenMP] Clang aborts for collapse clause with imprefect nested loops #60768

Open
kiranktp opened this issue Feb 15, 2023 · 20 comments
Open
Assignees
Labels
clang:codegen clang:openmp OpenMP related changes to Clang crash Prefer [crash-on-valid] or [crash-on-invalid]

Comments

@kiranktp
Copy link
Contributor

kiranktp commented Feb 15, 2023

Variable jb defined in outer loop causing the Clang to abort:
Initial investigation showed that the variable jb was not registered in LocalDeclMap.

$ cat -n test.c
1  void func( double *A, int N, int M, int NB ) {
2  #pragma omp parallel
3      {
4          int nblks = (N-1)/NB;
5          int lnb = ((N-1)/NB)*NB;
6  #pragma omp for collapse(2)
7          for (int jblk = 0 ; jblk < nblks ; jblk++ ) {
8              **int jb = (jblk == nblks - 1 ? lnb : NB);**
9              for ( int jk = 0 ; jk < jb ; jk++ ) {
10              }
11          }
12      }
13  }
$ clang --version
clang version 16.0.0 (https://github.com/llvm/llvm-project.git a28f3f8e48cb3935d413d3b9c0fcd5f72dcd5b8a)
...
$ clang -c -fopenmp test.c
DeclRefExpr for Decl not entered in LocalDeclMap?
UNREACHABLE executed at /home/user/llvm-flang-src/llvm-project/clang/lib/CodeGen/CGExpr.cpp:2842!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: /home/user/llvm-flang-src/llvm-project/install_rel/bin/clang -c -fopenmp test.c
1.      <eof> parser at end of file
2.      Per-file LLVM IR generation
3.      test.c:1:6: Generating code for declaration 'func'
4.      test.c:3:5: LLVM IR generation of compound statement ('{}')
	#0 0x00007f10ccd3de63 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/user/llvm-flang-src/llvm-project/llvm/lib/Support/Unix/Signals.inc:567:13
 #1 0x00007f10ccd3bc4e llvm::sys::RunSignalHandlers() /home/user/llvm-flang-src/llvm-project/llvm/lib/Support/Signals.cpp:105:18
	#2 0x00007f10ccd3d28d llvm::sys::CleanupOnSignal(unsigned long) /home/user/llvm-flang-src/llvm-project/llvm/lib/Support/Unix/Signals.inc:0:3
	#3 0x00007f10ccc4833e (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) /home/user/llvm-flang-src/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp:77:5
	#4 0x00007f10ccc48590 CrashRecoverySignalHandler(int) /home/user/llvm-flang-src/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp:398:1
	#5 0x00007f10cc5d0520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
	#6 0x00007f10cc624a7c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
	#7 0x00007f10cc624a7c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
	#8 0x00007f10cc624a7c pthread_kill ./nptl/pthread_kill.c:89:10
	#9 0x00007f10cc5d0476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
#10 0x00007f10cc5b67f3 abort ./stdlib/abort.c:81:7
#11 0x00007f10ccc5d7f1 (/home/user/llvm-flang-src/llvm-project/install_rel/bin/../lib/libLLVMSupport.so.16git+0x1747f1)
#12 0x00007f10d0cf0468 clang::CodeGen::CodeGenFunction::EmitDeclRefLValue(clang::DeclRefExpr const*) /home/user/llvm-flang-src/llvm-project/clang/lib/CodeGen/CGExpr.cpp:0:0
#13 0x00007f10d0ce2541 clang::CodeGen::CodeGenFunction::EmitLValue(clang::Expr const*) /home/user/llvm-flang-src/llvm-project/clang/lib/CodeGen/CGExpr.cpp:0:12
#14 0x00007f10d0cec9ab clang::CodeGen::CodeGenFunction::EmitCheckedLValue(clang::Expr const*, clang::CodeGen::CodeGenFunction::TypeCheckKind) /home/user/llvm-flang-src/llvm-project/clang/lib/CodeGen/CGExpr.cpp:1241:8
		......
@llvmbot
Copy link
Member

llvmbot commented Feb 15, 2023

@llvm/issue-subscribers-clang-codegen

@llvmbot
Copy link
Member

llvmbot commented Feb 15, 2023

@llvm/issue-subscribers-openmp

@EugeneZelenko EugeneZelenko added the crash Prefer [crash-on-valid] or [crash-on-invalid] label Feb 15, 2023
@jdoerfert
Copy link
Member

Verified with trunk: https://godbolt.org/z/K4Mob595f

@alexey-bataev
Copy link
Member

Does it meet the requirements for the canonical loop nest?

@kiranktp
Copy link
Contributor Author

kiranktp commented Jul 24, 2023

As i understand there is a change in the standard from 5.0 to 5.1

OpenMP 5.0: Restrictions under "2.9.2 Worksharing-Loop Construct":


...
� If a collapse clause is specified, exactly one loop must occur in the region at each nesting
level up to the number of loops specified by the parameter of the collapse clause.
...


IMO, It means the loop has to be perfectly nested loop.

Where as this restriction has been removed in OpenMP 5.1: Restrictions under "2.11.4 Worksharing-Loop Construct".

There is a corresponding code change in clang as well:
lib/Sema/SemaOpenMP.cpp:
9569 /// Called on a for stmt to check itself and nested loops (if any).
9570 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9571 /// number of collapsed loops otherwise.
9572 static unsigned
9573 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9574 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9575 DSAStackTy &DSA,
9576 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9577 OMPLoopBasedDirective::HelperExprs &Built) {
9578 unsigned NestedLoopCount = 1;
9579 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9580 !isOpenMPLoopTransformationDirective(DKind);

I means, Non perfectly nested loops are allowed.
My understanding correct?

All GNU based compilers and intel proprietary compiler throw an error for this test case:

error: not enough perfectly nested loops before 'int
Where as all clang based compiler allow this and crashes later during symbol resolution.

What should compiler do for this test case?

@alexey-bataev
Copy link
Member

It is not only nob-perfectly nested. According to 4.4.1 Canonical Loop Nest Form, lb/ub (jb in this example) "Expressions of a type compatible with the type of var that are loop invariant with respect to the outermost loop.". In this example jb is not outermost loop invariant.

@nvarj
Copy link

nvarj commented Feb 13, 2024

According to this "Expressions of a type compatible with the type of var that are loop invariant with respect to the outermost loop." statement from the standard, type of lb or ub used in nested loops should be compatible with type of var that is a loop invariant in outermost loop. Here type of jb and type of var that are loop invariant with respect to outermost loop are compatible. Both are of type integer. Hence the test case should be valid right?

@alexey-bataev
Copy link
Member

It is not a type issue, jb is not a outer loop invariant. Crashing is not good, though, need to emit error message.

@nvarj
Copy link

nvarj commented Mar 11, 2024

@alexey-bataev Are you planning to fix this issue?

@alexey-bataev
Copy link
Member

No, you can do it.

@Meinersbur
Copy link
Member

Meinersbur commented Mar 11, 2024

If a collapse clause is specified, exactly one loop must occur in the region at each nesting level up to the number of loops specified by the parameter of the collapse clause.

I don't think this ever prohibited imperfectly nested loops. The restriction requires that there are at least as many loops as specified by the collapse clause. Nothing is said about whether they are perfectly or imperfectly nested.

The feature history of 5.0 even mentions it explicitly:
image

@nvarj
Copy link

nvarj commented Mar 13, 2024

So the compiler should be allowing the test case to pass?

@shiltian shiltian changed the title Clang aborts for collapse clause with imprefect nested loops [OpenMP 5.1] [Clang][OpenMP] Clang aborts for collapse clause with imprefect nested loops Mar 13, 2024
@shiltian
Copy link
Contributor

By no means should the compiler crash, so definitely it is an issue.

@alexey-bataev
Copy link
Member

By no means should the compiler crash, so definitely it is an issue.

Definitely.

@EugeneZelenko EugeneZelenko added clang:openmp OpenMP related changes to Clang and removed openmp labels Mar 13, 2024
@Meinersbur
Copy link
Member

Meinersbur commented Mar 13, 2024

So the compiler should be allowing the test case to pass?

My comment was to argue that the input was already valid OpenMP since 5.01, not just since Open 5.1.

Footnotes

  1. If it was not, it would be a crash on invalid input, which could be argued is a lower priority issue. It's not difficult to make Clang crash on arbitrary inputs. It's a moot point since we also want to support OpenMP 5.1 anyway.

@alexey-bataev
Copy link
Member

So the compiler should be allowing the test case to pass?

My comment was to argue that the input was already valid OpenMP since 5.01, not just since Open 5.1.

Footnotes

  1. If it was not, it would be a crash on invalid input, which could be argued is a lower priority issue. It's not difficult to make Clang crash on arbitrary inputs. It's a moot point since we also want to support OpenMP 5.1 anyway.

What do you mean by "valid"? That it should not crash the compiler? In this case it should be "valid" as soon as multi-collapsing is supported. The fact here that the input is "invalid" because lb is not outer loop invariant. But it does not mean that the compiler should crash.

@Meinersbur
Copy link
Member

Meinersbur commented Mar 13, 2024

@alexey-bataev Correct, I missed that the crashing case was referring to a loop-variant local variable that is not a loop iteratation variable. I was only trying address the misunderstanding that collapsing non-perfectly loops was new in OpenMP 5.1.

@alexey-bataev
Copy link
Member

Am, I still think the crash should be fixed, the compiler still crashes

@nvarj
Copy link

nvarj commented Mar 13, 2024

The crash should definitely be fixed. So the compiler should be throwing an error about the variable right.

@jtb20
Copy link
Contributor

jtb20 commented Jul 31, 2024

#101305 (apologies for my confusion about GitHub issue numbers vs. PR numbers...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen clang:openmp OpenMP related changes to Clang crash Prefer [crash-on-valid] or [crash-on-invalid]
Projects
None yet
Development

No branches or pull requests

9 participants