<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">On 10/10/2018 4:27 PM, Taylor Cramer
      via llvm-dev wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAFVyvB+jPNenhgBB_=8Uov6bvyZM6ZpNy07L0qy4-xD6mvf-Ow@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <div dir="ltr">The <a
          href="https://llvm.org/docs/LangRef.html#volatile-memory-accesses"
          target="_blank" moz-do-not-send="true">language reference</a> says
        that <span class="gmail-il">LLVM</span> optimizers must not
        change the number of volatile operations or change their order
        of execution relative to other volatile operations. However, it
        doesn't say that optimizers can't introduce non-volatile
        operations. Is there any way to write IR that would ensure the
        generated loads and stores exactly match the number and ordering
        of the loads and stores in the source IR? I've heard conflicting
        reports about this. I'm specifically interested in manipulating
        MMIO, where loads and stores may have side effects.
        <div>
          <div><br>
          </div>
          <div>If it is in fact possible to prevent the insertion of
            loads/stores, does the presence of the "dereferenceable"
            attribute on pointers have any affect here? Will marking a
            pointer "dereferenceable" allow loads/stores to a
            volatile-only-accessed memory location that wouldn't be
            allowed otherwise?</div>
        </div>
        <div><br>
        </div>
        <div>Context: this discussion originated in <a
            href="https://github.com/rust-rfcs/unsafe-code-guidelines/issues/33"
            target="_blank" moz-do-not-send="true">an issue on the Rust
            unsafe code guidelines issue tracker</a>.</div>
      </div>
    </blockquote>
    <br>
    <a class="moz-txt-link-freetext" href="http://llvm.org/docs/LangRef.html#pointer-aliasing-rules">http://llvm.org/docs/LangRef.html#pointer-aliasing-rules</a> says "Any
    memory access must be done through a pointer value associated with
    an address range of the memory access, otherwise the behavior is
    undefined."<br>
    <br>
    From LLVM's perspective, we can refer to all the memory which can
    possibly be accessed according to those rules as "allocated
    memory".  A non-volatile memory access can only access allocated
    memory.  MMIO registers are not allocated memory; they do not behave
    the way LLVM expects memory to behave.  So a non-volatile load from
    an MMIO register has undefined behavior.  And a pointer marked
    dereferenceable cannot point to an MMIO register, or the behavior is
    undefined.<br>
    <br>
    volatile accesses are special; they have target-specific semantics,
    so they can access MMIO registers even though that isn't allowed for
    a non-volatile load.<br>
    <br>
    In practice, this means your code will do what you want as long as
    all MMIO accesses are volatile.<br>
    <br>
    -Eli
    <pre class="moz-signature" cols="72">-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project</pre>
  </body>
</html>