[PATCH] D118102: [LoopInterchange] Prevent interchange with unsafe control-flow divergence inside inner loops (PR48057)

Michael Kruse via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 1 09:31:21 PST 2022


Meinersbur added a comment.

In D118102#3280506 <https://reviews.llvm.org/D118102#3280506>, @congzhe wrote:

> Nevertheless if the store is executed every time (not diverging), IMHO if I'm not mistaken, it seems that this output dependency does not invalid loop interchange since we only care about the final value written into @e, which is the value of array b[d][0] at the final interation. This value b[d=0][0] does not change before and after interchange. So the output dependence is this example seems to be okay, please correct me if I'm wrong.

Traditional dependency analysis only considers pairwises dependencies ("hazards") between to execution, which is formulated like "StmtA(i) and StmtB(j) are dependent if they may access the same memory at least on of them is a write" (Read-after-Read is not a dependency). In principle an output-dependency does not matter if overwritten anyway before being used. However, DependenceAnalysis doesn't even have an API to consider that. It also does not make a difference between "unconditionally overwrite" (in literature called a "kill") and a conditional or partial write:

  bool Dependence::isOutput() const {
    return Src->mayWriteToMemory() && Dst->mayWriteToMemory();
  }



> Regarding dependency analysis: for this example (e.g., `test1()` in `pr48057.ll`), no dependence is detected, since for all mem instructions (on lines 57, 63 ,65 in `pr48057.ll`), the memory locations do not alias.

`store i16 %conv9.i, i16* @e` hazards with itself from different iterations (same memory, both are "write"). It would not be very different if it was an array and indexed `e[f(d,c)]` where `f` is a speculable/const function (and potentially always returns `0`). If no dependence is detected, I'd consider it a bug.



================
Comment at: llvm/test/Transforms/LoopInterchange/pr48057.ll:13-22
+; char b[][8] = {{}, {}, {}, {}, {5}, {}, 2, 3};
+; int c, d;
+; short e;
+; static char test1() {
+;   for (; c <= 7; c++) {
+;     d = 4;
+;     for (; d; d--)
----------------
Instead of using the fuzzer output, it would be nice to reduce it making it more similar to what a user would write (e.g. avoid globals, explicit loop variables, etc). Eg.:
```
void test1(char b[][5], int *e) {
   for (int c = 0; c < 8; ++c) 
     for (int d = 0; d < 5; ++d)
       if(b[c][d])
         *e = c + d;
 }
```



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D118102/new/

https://reviews.llvm.org/D118102



More information about the llvm-commits mailing list