[EarlyCSE] Do not CSE convergent calls in different basic blocks
authorJay Foad <jay.foad@amd.com>
Thu, 27 Apr 2023 12:43:11 +0000 (13:43 +0100)
committerJay Foad <jay.foad@amd.com>
Fri, 28 Apr 2023 13:50:48 +0000 (14:50 +0100)
commit56af0e913ce7ec29690cc7295d75fc5573153bbf
treeb8dd4209e8015f355d19b7495e99c8ce00533557
parent5534d1d834c25ec6a3755a44b46e2489b7d0ccf9
[EarlyCSE] Do not CSE convergent calls in different basic blocks

"convergent" is documented as meaning that the call cannot be made
control-dependent on more values, but in practice we also require that
it cannot be made control-dependent on fewer values, e.g. it cannot be
hoisted out of the body of an "if" statement.

In code like this, if we allow CSE to combine the two calls:

  x = convergent_call();
  if (cond) {
    y = convergent_call();
    use y;
  }

then we get this:

  x = convergent_call();
  if (cond) {
    use x;
  }

This is conceptually equivalent to moving the second call out of the
body of the "if", up to the location of the first call, so it should be
disallowed.

Differential Revision: https://reviews.llvm.org/D149348
llvm/lib/Transforms/Scalar/EarlyCSE.cpp
llvm/test/CodeGen/AMDGPU/cse-convergent.ll