This is an archive of the discontinued LLVM Phabricator instance.

[llvm] GVN.cpp: Do not swap when both LHS and RHS are arguments.
AbandonedPublic

Authored by hiraditya on Apr 6 2016, 9:01 AM.

Details

Summary

Prevent swapping of operands when both LHS and RHS are arguments.
Passes llvm regression

Diff Detail

Repository
rL LLVM

Event Timeline

hiraditya updated this revision to Diff 52811.Apr 6 2016, 9:01 AM
hiraditya retitled this revision from to [llvm] GVN.cpp: Do not swap when both LHS and RHS are arguments..
hiraditya updated this object.
hiraditya set the repository for this revision to rL LLVM.
hiraditya added a subscriber: llvm-commits.
In D18830#393321, @joker.eph wrote:

Test?

I came across this when I was reading the code, as such I do not know how to come up with a test case for this specific case.

I don't believe this case is testable, because line 1904 should swap them
back into the right order anyway.
All this patch will do is avoid extra work.

mcrosier edited edge metadata.Apr 6 2016, 10:28 AM

I don't believe this case is testable, because line 1904 should swap them
back into the right order anyway.
All this patch will do is avoid extra work.

Am I correct in assuming this LGTY, Daniel?

Oh then it is not even clear if it is worth it (avoid extra work here is doing an extra comparison to avoid a "pointer swap")

In D18830#393400, @joker.eph wrote:

Oh then it is not even clear if it is worth it (avoid extra work here is doing an extra comparison to avoid a "pointer swap")

It seems VN.lookupOrAdd only swaps operands based on value numbers. Preferring constants/arguments on RHS seems unrelated to that, although I'm not sure this preference is useful in anyway.

chandlerc requested changes to this revision.Apr 7 2016, 1:33 AM
chandlerc edited edge metadata.

Please don't avoid extra work in this way IMO, unless you have a very significant compile time hit due to this.

We have a pervasive reliance on canonicalizing constants to the RHS of binary operations so those should be exceedingly rare anyways. We shouldn't fight that, we should run with it.

My two cents. If Danny, Chad, or others working more on GVN disagree, they can happily override me. =D

This revision now requires changes to proceed.Apr 7 2016, 1:33 AM

My two cents. If Danny, Chad, or others working more on GVN disagree, they can happily override me. =D

FWIW, I don't disagree with Chandler's opinion.

Please don't avoid extra work in this way IMO, unless you have a very significant compile time hit due to this.

We have a pervasive reliance on canonicalizing constants to the RHS of binary operations so those should be exceedingly rare anyways. We shouldn't fight that, we should run with it.

My two cents. If Danny, Chad, or others working more on GVN disagree, they can happily override me. =D

Thanks for the feedback. This patch will not change the order of preference (RHS should keep Constants/Arguments). it only prevents swap when both LHS and RHS are Arguments.

I think his point is more the same one i made: "we shouldn't have to swap
at all, and if we do, we should fix that"

Please approve the patch, if it looks okay.

Thanks,

mcrosier resigned from this revision.Apr 18 2016, 1:31 PM
mcrosier removed a reviewer: mcrosier.

@dberlin
Please approve the patch if you are fine with it.

Thanks,

Chandler explicitly requested we take a different approach, and while I
could overrule him, not sure it's worth it for this patch.
I think we have spent more time on this thank it would take to track down
every place generating it that ends up needing to be swapped and fixing it
at the source

What Danny said here.

It feels like this patch is papering over failure to canonicalize. To make
progress we need to either:

a) Show a super clear example where there *is no canonicalization*. That
is, one usage wants one canonicalization and the other wants the other, so
we have to support both. If you can show that we cannot canonicalize this
because it is in tension with other canonicalization, that is exactly the
motivation that folks have asked for to land this patch.

or...

b) Fix everything to canonicalize so this patch isn't necessary.

hiraditya added a comment.EditedApr 28 2016, 6:07 AM

So to generate examples where there are redundant swaps, I used this patch.

--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1892,8 +1892,13 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS, const BasicBlockEdge &Root,
       continue;

     // Prefer a constant on the right-hand side, or an Argument if no constants.
-    if (isa<Constant>(LHS) || (isa<Argument>(LHS) && !isa<Constant>(RHS)))
+    if (isa<Constant>(LHS)
+        || (isa<Argument>(LHS) && !isa<Constant>(RHS))){
       std::swap(LHS, RHS);
+      if (isa<Argument>(LHS) && isa<Argument>(RHS))
+        llvm_unreachable("testcase: swapped once");
+    }
+

Following 7 test cases triggered with this patch:

./bin/opt < llvm/test/Transforms/GVN/2008-07-02-Unreachable.ll -basicaa -gvn -S | grep "ret i8 [%]tmp3"

./bin/opt < llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll -basicaa -gvn -S

./bin/opt < llvm/test/Transforms/GVN/local-pre.ll -gvn -enable-pre -S

./bin/opt < llvm/test/Transforms/GVN/condprop.ll -basicaa -gvn -S

./bin/opt < llvm/test/Transforms/GVN/rle-semidominated.ll -basicaa -gvn -S

./bin/opt < llvm/test/Transforms/GVN/rle.ll -default-data-layout="E-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-n32" -basicaa -gvn -S -die

./bin/opt < llvm/test/Transforms/GVN/rle-nonlocal.ll -basicaa -gvn -S

Ok, so this is eliminating swaps. But these are just pointer swaps -- what is the motivation for eliminating them? What does that improve?

sebpop resigned from this revision.Sep 20 2016, 7:59 AM
sebpop removed a reviewer: sebpop.
hiraditya abandoned this revision.Mar 1 2017, 9:46 AM