This is an archive of the discontinued LLVM Phabricator instance.

[MLIR][SCF] Canonicalize while statement whose cmp condition is recomputed in the after region
ClosedPublic

Authored by wsmoses on Jan 11 2022, 12:43 PM.

Details

Summary

Given a while loop whose condition is given by a cmp, don't recomputed the comparison (or its inverse) in the after region, instead use a constant since the original condition must be true if we branched to the after region.

Diff Detail

Event Timeline

wsmoses created this revision.Jan 11 2022, 12:43 PM
wsmoses requested review of this revision.Jan 11 2022, 12:43 PM
mehdi_amini added inline comments.Jan 11 2022, 12:52 PM
mlir/lib/Dialect/SCF/SCF.cpp
2468

Shouldn't this be handled in CSE: the expression in the do block should be hoisted in the condition block here?

wsmoses added inline comments.Jan 11 2022, 1:01 PM
mlir/lib/Dialect/SCF/SCF.cpp
2468

Will CSE actually hoist from the do block into the while? Running this test on CSE, implies no (though that would certainly be desirable).

Regardless, this also handles the case where the condition is the negation.

wsmoses added inline comments.Jan 11 2022, 1:02 PM
mlir/lib/Dialect/SCF/SCF.cpp
2468

I think part of the reason CSE can't perform this hoisting is because the argument's aren't completely the same (e.g. the later comparison uses the block arguments, which are only defined at the start of the after region).

rriddle added inline comments.Jan 11 2022, 1:06 PM
mlir/lib/Dialect/SCF/SCF.cpp
2496–2497

Do you have coverage for when this gets hit twice?

mehdi_amini added inline comments.Jan 11 2022, 2:23 PM
mlir/lib/Dialect/SCF/SCF.cpp
2468

Will CSE actually hoist from the do block into the while? Running this test on CSE, implies no (though that would certainly be desirable).

Right, I didn't mean that CSE already implements it, just that this is where it belongs :)

2483
2496–2497

I suspect we'll be missing an make_early_inc_range for the for (auto &u : std::get<1>(tup).getUses()) {

wsmoses updated this revision to Diff 399082.Jan 11 2022, 2:32 PM

Address comments

mehdi_amini accepted this revision.Jan 11 2022, 2:35 PM
This revision is now accepted and ready to land.Jan 11 2022, 2:35 PM
rriddle added inline comments.Jan 11 2022, 2:38 PM
mlir/lib/Dialect/SCF/SCF.cpp
2482

Can you negate this and use early continue to reduce nesting?

2494–2496

Is it possible for u.getOwner() to have multiple uses of the value?

wsmoses updated this revision to Diff 399086.Jan 11 2022, 2:42 PM

Address comments

wsmoses marked 6 inline comments as done.Jan 11 2022, 2:44 PM
wsmoses added inline comments.
mlir/lib/Dialect/SCF/SCF.cpp
2494–2496

No, as the owner is the comparison cmp2, which has its rhs equal to the comparison in the before block's rhs (and thus cannot be a blockArg to the after region).

mehdi_amini added inline comments.Jan 11 2022, 2:48 PM
mlir/lib/Dialect/SCF/SCF.cpp
2494–2496

I don't think so because of the condition line 2489? (if (cmp2.getRhs() != cmp.getRhs()))

By the way this make the pattern only catch one side isn't it? If I just reverse the operands we'll bail out:

  %condition = arith.cmpi ne, %arg0, %val : i32
  scf.condition(%condition) %val : i32
} do {
^bb0(%val2: i32):
  %condition2 = arith.cmpi ne,  %arg0, %val2 : i32
  %negcondition2 = arith.cmpi eq, %arg0, %val2 : i32
  "test.use"(%condition2, %negcondition2, %val2) : (i1, i1, i32) -> ()

Also it seems like it won't handle cases where both operands come from the condition block.

wsmoses updated this revision to Diff 399095.Jan 11 2022, 3:03 PM

Handle both sides of comparison