[PATCH] D26348: Allow convergent attribute for function arguments

Matias Goldberg via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 7 11:02:00 PST 2017


dark_sylinc added a comment.

In https://reviews.llvm.org/D26348#694427, @sanjoy wrote:

> Is it okay to fold that to:
>
>   void foo(int v, bool cond) {
>     if (cond) {
>       // token1 = statepoint()
>       // bar(v, token1); // v needs to be convergent
>     } else {
>       // token2 = statepoint()
>       // bar(v, token2);  // v needs to be convergent
>     }
>     token_merged = statepoint()
>     bar(v, token_merged); // v needs to be convergent
>   }
>


Yes, that is ok.

Examples that are **ok** to fold:

  //Example 1: Safe to fold.
  void foo(int v, bool cond) {
    if (cond) {
      // token1 = statepoint()
      // bar(v, token1); // v needs to be convergent
    } else {
      // token2 = statepoint()
      // bar(v, token2);  // v needs to be convergent
    }
    token_merged = statepoint()
    bar(v, token_merged); // v needs to be convergent
  }
  
  //Example 2: Unsafe to fold, but the language allows it thus it's programmer's
  //responsibility to ensure correctness through data fed to the machine.
  void foo(int v, bool cond) {
    token = statepoint()
    if (cond) {
      //idx0 = statepoint();
    } else {
      //idx1 = statepoint();
    }
    idx3 = phi[idx0, idx1];
    bar(v[idx3], token); // v needs to be convergent
  }
  
  //Example 3: Safe to fold, proven at compile time that v1 == v2
  void foo(int v, bool cond) {
    token = statepoint()
    if (cond) {
      // v1 = statepoint()
      // bar(v1, token); // v needs to be convergent
    } else {
      // v2 = statepoint()
      // bar(v2, token);  // v needs to be convergent
    }
    //proven at compile time that v1 == v2 or that cond is always true / always false
    bar(v1, token); // v needs to be convergent
  }
  
  //Example 4: Safe to fold, proven at compile time that idx0 == idx1
  void foo(int v, bool cond) {
    token = statepoint()
    if (cond) {
      //idx0 = statepoint();
    } else {
      //idx1 = statepoint();
    }
    //proven at compile time that idx1 == idx2 or that cond is always true / always false
    bar(v[idx1], token); // v needs to be convergent
  }

Examples that is **NOT** ok to fold:

  //Example 5 Unsafe to fold, should not be fold.
  void foo(int v, bool cond) {
    token = statepoint()
    if (cond) {
      // v1 = statepoint()
      // bar(v1, token); // v needs to be convergent
    } else {
      // v2 = statepoint()
      // bar(v2, token);  // v needs to be convergent
    }
    v_merged = phi[v1, v2]
    bar(v_merged, token); // v needs to be convergent
  }
  
  //Example 6: (HLSL only) Unsafe to fold and programmer explicitly requested not to fold through language semantics (NonUniformResourceIndex).
  //This is identical to Example 2, except the programmer explicitly asked not to fold through a special keyword or intrinsic.
  //As far as I can see support for differentiating between these two scenarios is beyond the scope of this patch.
  void foo(int v, bool cond) {
    token = statepoint()
    if (cond) {
      //idx0 = statepoint();
    } else {
      //idx1 = statepoint();
    }
    idx3 = noncovergent_phi[idx0, idx1];
    bar(v[idx3], token); // v needs to be convergent
  }


https://reviews.llvm.org/D26348





More information about the llvm-commits mailing list