[llvm-dev] [RFC] Refinement of convergent semantics

Philip Reames via llvm-dev llvm-dev at lists.llvm.org
Mon Sep 14 12:15:48 PDT 2015


On 09/04/2015 01:25 PM, Owen Anderson via llvm-dev wrote:
> Hi all,
>
> In light of recent discussions regarding updating passes to respect convergent semantics, and whether or not it is sufficient for barriers, I would like to propose a change in convergent semantics that should resolve a lot of the identified problems regarding loop unrolling, loop unswitching, etc.  Credit to John McCall for talking this over with me and seeding the core ideas.
>
> Today, convergent operations may only be moved into control-equivalent locations, or, in layman’s terms, a convergent operation may neither be sunk into nor hoisted out of, a condition.  This causes problems for full loop unrolling, as the control dependence on the loop counter is eliminated, but our intuition indicates that this dependence was somehow trivial.  More concretely, all know uses of convergent are OK with full unrolling, making this semantic undesirable.  Related problems arise in loop unswitching as well.
I don't understand this point.  Loop unrolling specifically won't change 
which indices actually run.  It might result in code duplication with a 
subset of indices taken one of two paths.  Does today's convergent also 
imply no-duplicate?  Is that what you're trying to relax?
>
> The proposed change is to split the semantics of convergent into two annotations:
> 	convergent - this operation may not be made control dependent on any additional values (aka may not be sunk into a condition)
To be clear, this is a restriction of current semantics only right?
> 	nospeculate - this operation may not be added to any program trace on which it was not previously executed (same as notrap?)
Isn't this already true of all instructions?  Unless we can *prove* that 
speculating an instruction can't introduce faults, we can't speculate it 
ever.  An unknown call or intrinsic should already have this property right?

This part of the proposal doesn't feel mature to me.  In particular, I 
think we need to talk about what other cases we want to handle w.r.t. 
speculation attributes and what our model is.

One case I want to support is for small functions which only read 
argument memory (i.e. argmemonly readonly nounwind) which are guaranteed 
(by the frontend) to fault only if a) the pointer passed in is null, or 
b) the memory state on entry is different that the one the context 
should have ensured.  (The second part is standard. The first allows 
speculation in more cases.)

I'd suggest promoting this to it's own thread.  Once we settle on a 
workable model for safe speculation attributes, we can revisit how we 
want to change the convergent attribute.

>
> Most of today’s convergent operations (barriers, arithmetic gradients) would continue to be marked only as convergent.  The new semantics would allow full loop unrolling, and provide clarity on which loop unswitching operations are allowed, examples below.
>
> The one case where nospeculate would also be needed is in the case of texture fetches that compute implicit gradients.  Because the computed gradient forms part of the addressing mode, gibberish gradients here can cause invalid memory dereferences.
>
> —Owen
>
> ——————————————————
>
> Loop Unswitching Examples
>
> ALLOWED:
> for (…) {
>    if (c) { convergent(); }
> }
>
> DISALLOWED:
> for (…) {
>    if (c) { … }
>    convergent();
> }
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list