[PATCH] D71578: [CodeMoverUtils] Improve IsControlFlowEquivalent.

Whitney Tsang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 20 16:18:16 PDT 2020


Whitney marked an inline comment as done.
Whitney added inline comments.


================
Comment at: llvm/lib/Transforms/Utils/CodeMoverUtils.cpp:320
+  DT.updateDFSNumbers();
+  const bool MoveForward = OI.dfsBefore(&I, &InsertPoint);
   if (MoveForward) {
----------------
nikic wrote:
> Whitney wrote:
> > fhahn wrote:
> > > nit: I think it would be clearer to use OI.dominates, like t line 333. I think with OI.dominates, the DFS numbers should be updated on demand, automatically.
> > I intensionally use OI.dfsBefore instead of OI.dominates, as they are not equivalent.  Unit test IsSafeToMoveTest2 illustrate the need. 
> Just stumbled across this while trying to eliminate the OrderedInstructions use: The use of `dfsBefore` here doesn't really make sense. The dfsBefore check can luck out and give you a correct result if both I and InsertPoint *happen* to be on the same DFS path, but there's no guarantee that this is the case. You can easily see this by swapping the block order in the IsSafeToMoveTest2 test case:
> 
> ```
> diff --git llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp
> index cf764bf76f06..dc70c6c52717 100644
> --- llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp
> +++ llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp
> @@ -555,13 +555,13 @@ TEST(CodeMoverUtils, IsSafeToMoveTest2) {
>    std::unique_ptr<Module> M =
>        parseIR(C, R"(define void @foo(i1 %cond, i32 %op0, i32 %op1) {
>                   entry:
> -                   br i1 %cond, label %if.then.first, label %if.end.first
> +                   br i1 %cond, label %if.end.first, label %if.then.first
>                   if.then.first:
>                     %add = add i32 %op0, %op1
>                     %user = add i32 %add, 1
>                     br label %if.end.first
>                   if.end.first:
> -                   br i1 %cond, label %if.then.second, label %if.end.second
> +                   br i1 %cond, label %if.end.second, label %if.then.second
>                   if.then.second:
>                     %sub_op0 = add i32 %op0, 1
>                     %sub = sub i32 %sub_op0, %op1
> ```
> 
> This will make both queries return true instead of false, which is obviously not right.
> 
> I don't know how to make this code correct though, or how a notion of "forward" or "backward" on a graph would be rigorously defined.
> 
> You can of course make the code conservatively correct by requiring that I dominates InsertPoint or InsertPoint dominates I, but from what I understood you're specifically interested in cases where this is not the case.
You are right, it is incorrect to use `dfsBefore` here. I am thinking to create a `bfsBefore`, which should gives correct result no matter for the original `IsSafeToMoveTest2` or the modified `IsSafeToMoveTest2`. 

Why do you want to eliminate the use of `OrderedInstructions`, should I add `bfsBefore` there?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71578





More information about the llvm-commits mailing list