Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Is this still WIP or should it be reviewed? Needs a proper commit message.
clang/lib/CodeGen/CGStmtOpenMP.cpp | ||
---|---|---|
5797–5800 | This looks like something is missing. |
clang/include/clang/AST/StmtOpenMP.h | ||
---|---|---|
2797–2824 | It is worth it to pre-commit these and related changes in a separate NFC patch | |
2848–2851 | Can we pack it into a struct? At least X, V etc. params? | |
clang/lib/CodeGen/CGStmtOpenMP.cpp | ||
5775–5802 | I would think about moving most of the atomic codegen functionality to common runtime/OMPBuilder part to be able to override implementation for different targets. It may help to avoid codegen problems with Nvidia/AMD GPUs. Not directly related to this patch though. |
clang/lib/CodeGen/CGStmtOpenMP.cpp | ||
---|---|---|
5775–5802 | yeah, actually IIRC the OMPIRBuilder already supports atomic operations. Not sure if it supports the compare clause but I'll take a look. If not, I also think it's a better place to sit them. |
Thanks for uploading this.
I tried it locally and it is missing proper parsing +sema of the cond-expr-stmt and cond-update-stmt as indicate in the openmp 5.1 spec's. I am sure you are aware of this and this is still WIP.
Do you plan to add support for that? The regression test is not exposing conditional statements, but update ones, so it is not really testing what it should.
You might also want to split parse+sema support from codegen, if it helps.
Many thanks again!
Yes, there are a couple of issues of implicit cast to be fixed. Current test is just a placeholder. I copied and pasted from the one for update clause and just replaced all updates with compare. I’m also working on that.
- Ignore implicit cast in some cases.
- Add the test case.
What are still missing:
- Code generation for floating point types.
Question:
- What atomic instruction(s) should we use for floating point types? Current I can see we do support floating point types for update clause, but the emitted code doesn't look like atomic operations.
- When do we have to use IgnoreParenImpCasts?
Another thing is how we deal with a corner case. Say the OpenMP code is written in the following way:
#pragma omp atomic compare x = e < x ? e : x;
That's how OpenMP spec defines the atomic operation. x is always in "else statement" of a conditional statement.
Now we need to lower it to LLVM IR, which is atomicrmw operation. Based on the LLVM IR reference, it only supports the atomic operations that x is in the "then statement". For example: x = x > e ? x : e. See the x here is before :. In order to lower the OpenMP statement, we have to do a transformation. In order to swap e and x, we need to transform it to x = e >= x : x : e, a.k.a. x = x <= e : x : e. However, we don't have an atomic operation for <=. We only have <. So if x != e, the result is good.
The incorrectness happens if x == e. Recall at the OpenMP statement, when x == e, the result should be x = x. But if we look at our lowered LLVM IR, x = x < e : x : e, when x == e, it becomes x = e, which doesn't conform with OpenMP spec.
What should we do here?
There seems to be an imbalance in the OpenMP specs, where I would have written something like the followin (page 268 or 5.1 spec's):
x = expr ordop x ? expr : x;
x = x ordop expr ? x : expr;
I tried thinking about a compact solution to your problem, including trying to take advantage of the fact that when x == e we don't need to actually do the assignment (page 272 line 17 of 5.1 spec's and see below), but I was unsuccessful.
Did you consider special casing this transforming it into the equivalent:
#pragma omp critical
{ if (x > e) x = e; }
?
Remember:
For forms where statement is cond-expr-stmt, if the result of the condition implies that the value of x
does not change then the update may not occur.
The right thing to do would be to fix the spec's, but that can't happen until 5.2.
This is already a lot of code with parse+sema. I wonder if we should split the patch into two, i.e. 1. parse+sema; 2. code gen? @ABataev ?
It should simplify maintenance of the patch and allow time to extend the OpenMP IR builder.
It is worth it to pre-commit these and related changes in a separate NFC patch