OSDN Git Service

[EarlyCSE] Ensure equal keys have the same hash value
authorJoseph Tremoulet <jotrem@microsoft.com>
Thu, 13 Jun 2019 15:24:11 +0000 (15:24 +0000)
committerJoseph Tremoulet <jotrem@microsoft.com>
Thu, 13 Jun 2019 15:24:11 +0000 (15:24 +0000)
commitabb2e449360224c78960fed7298b9ccb4d26debe
treeb93255e8439259588e680ebedb9ced3ae70a2d9b
parent15a180999a3ab45ecce7fb32ed5be7338e18272b
[EarlyCSE] Ensure equal keys have the same hash value

Summary:
The logic in EarlyCSE that looks through 'not' operations in the
predicate recognizes e.g. that `select (not (cmp sgt X, Y)), X, Y` is
equivalent to `select (cmp sgt X, Y), Y, X`.  Without this change,
however, only the latter is recognized as a form of `smin X, Y`, so the
two expressions receive different hash codes.  This leads to missed
optimization opportunities when the quadratic probing for the two hashes
doesn't happen to collide, and assertion failures when probing doesn't
collide on insertion but does collide on a subsequent table grow
operation.

This change inverts the order of some of the pattern matching, checking
first for the optional `not` and then for the min/max/abs patterns, so
that e.g. both expressions above are recognized as a form of `smin X, Y`.

It also adds an assertion to isEqual verifying that it implies equal
hash codes; this fires when there's a collision during insertion, not
just grow, and so will make it easier to notice if these functions fall
out of sync again.  A new flag --earlycse-debug-hash is added which can
be used when changing the hash function; it forces hash collisions so
that any pair of values inserted which compare as equal but hash
differently will be caught by the isEqual assertion.

Reviewers: spatel, nikic

Reviewed By: spatel, nikic

Subscribers: lebedev.ri, arsenm, craig.topper, efriedma, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D62644

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363274 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/Analysis/ValueTracking.h
lib/Analysis/ValueTracking.cpp
lib/Transforms/Scalar/EarlyCSE.cpp
test/Transforms/EarlyCSE/commute.ll