<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - clang CSE's __builtin_arm_rsr64 et al"
   href="https://bugs.llvm.org/show_bug.cgi?id=44687">44687</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>clang CSE's __builtin_arm_rsr64 et al
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>roland@hack.frob.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Test case:
```
#include <arm_acle.h>
#include <stdint.h>

// Workaround for Cortex-A73 erratum 858921.
uint64_t read_cntpct_a73(void) {
  const uint64_t old_read = __arm_rsr64("cntpct_el0");
  const uint64_t new_read = __arm_rsr64("cntpct_el0");
  return (((old_read ^ new_read) >> 32) & 1) ? old_read : new_read;
}
```

clang --target=aarch64-{fuchsia,linux} -O1 (or higher) compiles this to:
```
        .text
        .file   "aclecse.c"
        .globl  read_cntpct_a73         // -- Begin function read_cntpct_a73
        .p2align        2
        .type   read_cntpct_a73,@function
read_cntpct_a73:                        // @read_cntpct_a73
// %bb.0:
        mrs     x0, CNTPCT_EL0
        ret
.Lfunc_end0:
        .size   read_cntpct_a73, .Lfunc_end0-read_cntpct_a73
                                        // -- End function
```

It has folded the two __arm_rsr64 (aka __builtin_arm_rsr64) calls together.
This is not kosher for many uses of system registers.  I haven't checked
whether the related builtins like rsr and rsrp have the same problem, but it
would be wrong for them too.

The compiler needs to treat these builtins as having side effects even though
they just "read a value".

Using `-emit-llvm` shows that the CSE is happening in the front end:
```
; ModuleID = 'aclecse.c'
source_filename = "aclecse.c"
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux"
; Function Attrs: nounwind readonly
define dso_local i64 @read_cntpct_a73() local_unnamed_addr #0 {
  %1 = tail call i64 @llvm.read_register.i64(metadata !2)
  ret i64 %1
}
; Function Attrs: nounwind readonly
declare i64 @llvm.read_register.i64(metadata) #1
```</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>