[PATCH] D94712: Do not traverse ConstantData use-list in LookInterchange

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 16 07:24:32 PST 2021


fhahn added inline comments.


================
Comment at: llvm/lib/Transforms/Scalar/LoopInterchange.cpp:663-669
 static PHINode *findInnerReductionPhi(Loop *L, Value *V) {
-  for (Value *User : V->users()) {
-    if (PHINode *PHI = dyn_cast<PHINode>(User)) {
-      if (PHI->getNumIncomingValues() == 1)
-        continue;
-      RecurrenceDescriptor RD;
-      if (RecurrenceDescriptor::isReductionPHI(PHI, L, RD))
-        return PHI;
-      return nullptr;
-    }
+  for (PHINode &PHI : L->getHeader()->phis()) {
+    if (PHI.getNumIncomingValues() == 1 ||
+        !llvm::is_contained(PHI.incoming_values(), V))
+      continue;
+    RecurrenceDescriptor RD;
+    return RecurrenceDescriptor::isReductionPHI(&PHI, L, RD) ? &PHI : nullptr;
----------------
dexonsmith wrote:
> It looks like sometimes `findInnerReductionPhi` is running on ConstantData, which can come from another function (or module), and will eventually lose its use-lists (no one should walk the use-list of `i1 0`; usually anything they learn from that will be wrong).
> - @willir's current patch changes the order of iteration. I think we'll need to check compile-time if we do this.
> - Another option would be to return `nullptr` on `isa<ConstantData>()`, if it's correct.
> - If that's correct, should this return `nullptr` on `isa<Constant>()` more generally?
> If that's correct, should this return nullptr on isa<Constant>() more generally?

I think `findInnerReductionPhi` should never return anything other than `nullptr` for constants; it is looking for a reduction results, which should always be an instruction.

So returning `nullptr` on `isa<Constant>` seems the best way forward. It would also be good to add a test with LCSSA phis with constant incoming values, e.g something like the below to `llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll`

```
define i64 @test1([100 x [100 x i64]]* %Arr) {
entry:
  br label %for1.header

for1.header:                                         ; preds = %for1.inc, %entry
  %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc ]
  %sum.outer = phi i64 [ 0, %entry ], [ %const.lcssa, %for1.inc ]
  br label %for2

for2:                                        ; preds = %for2, %for1.header
  %indvars.iv = phi i64 [ 0, %for1.header ], [ %indvars.iv.next.3, %for2 ]
  %sum.inner = phi i64 [ %sum.outer, %for1.header ], [ %sum.inc, %for2 ]
  %arrayidx = getelementptr inbounds [100 x [100 x i64]], [100 x [100 x i64]]* %Arr, i64 0, i64 %indvars.iv, i64 %indvars.iv23
  %lv = load i64, i64* %arrayidx, align 4
  %sum.inc = add i64 %sum.inner, %lv
  %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 1
  %exit1 = icmp eq i64 %indvars.iv.next.3, 100
  br i1 %exit1, label %for1.inc, label %for2

for1.inc:                                ; preds = %for2
  %const.lcssa = phi i64 [ 1, %for2 ]
  %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
  %exit2 = icmp eq i64 %indvars.iv.next24, 100
  br i1 %exit2, label %for1.loopexit, label %for1.header

for1.loopexit:                                 ; preds = %for1.inc
  %const.lcssa2 = phi i64 [ %const.lcssa, %for1.inc ]
  ret i64 %const.lcssa2
}
```



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94712



More information about the llvm-commits mailing list