Commit 3d27c09b authored by Tom Stellard's avatar Tom Stellard
Browse files

Merging r318788:

------------------------------------------------------------------------
r318788 | mcrosier | 2017-11-21 10:08:34 -0800 (Tue, 21 Nov 2017) | 16 lines

[AArch64] Mark mrs of TPIDR_EL0 (thread pointer) as *having* side effects.

This partially reverts r298851.  The the underlying issue is that we don't
currently model the dependency between mrs (read system register) and
msr (write system register) instructions.

Something like the below should never be reordered:

 msr TPIDR_EL0, x0  ;; set thread pointer
 mrs x8, TPIDR_EL0  ;; read thread pointer

but was being reordered after r298851.  The functional part of the patch
that wasn't reverted needed to remain in place in order to not break
r299462.

PR35317
------------------------------------------------------------------------

llvm-svn: 318854
parent 6f6353af
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -441,8 +441,7 @@ def MSRpstateImm1 : MSRpstateImm0_1;
def MSRpstateImm4 : MSRpstateImm0_15;

// The thread pointer (on Linux, at least, where this has been implemented) is
// TPIDR_EL0.  Add pseudo op so we can mark it as not having any side effects.
let hasSideEffects = 0 in
// TPIDR_EL0.
def MOVbaseTLS : Pseudo<(outs GPR64:$dst), (ins),
                       [(set GPR64:$dst, AArch64threadpointer)]>, Sched<[WriteSys]>;

+0 −60
Original line number Diff line number Diff line
; RUN: llc -mtriple=aarch64-linux-gnu -verify-machineinstrs -o - %s | FileCheck %s

@x = thread_local local_unnamed_addr global i32 0, align 4
@y = thread_local local_unnamed_addr global i32 0, align 4

; Machine LICM should hoist the mrs into the loop preheader.
; CHECK-LABEL: @test1
; CHECK: BB#1:
; CHECK:   mrs x[[BASE:[0-9]+]], TPIDR_EL0
; CHECK:   add x[[REG1:[0-9]+]], x[[BASE]], :tprel_hi12:x
; CHECK:   add x[[REG2:[0-9]+]], x[[REG1]], :tprel_lo12_nc:x
;
; CHECK: .LBB0_2:
; CHECK:   ldr w0, [x[[REG2]]]
; CHECK:   bl bar
; CHECK:   subs w[[REG3:[0-9]+]], w{{[0-9]+}}, #1
; CHECK:   b.ne .LBB0_2

define void @test1(i32 %n) local_unnamed_addr {
entry:
  %cmp3 = icmp sgt i32 %n, 0
  br i1 %cmp3, label %bb1, label %bb2

bb1:
  br label %for.body

for.body:
  %i.04 = phi i32 [ %inc, %for.body ], [ 0, %bb1 ]
  %0 = load i32, i32* @x, align 4
  tail call void @bar(i32 %0) #2
  %inc = add nuw nsw i32 %i.04, 1
  %exitcond = icmp eq i32 %inc, %n
  br i1 %exitcond, label %bb2, label %for.body

bb2:
  ret void
}

; Machine CSE should combine the the mrs between the load of %x and %y.
; CHECK-LABEL: @test2
; CHECK: mrs x{{[0-9]+}}, TPIDR_EL0
; CHECK-NOT: mrs x{{[0-9]+}}, TPIDR_EL0
; CHECK: ret
define void @test2(i32 %c) local_unnamed_addr #0 {
entry:
  %0 = load i32, i32* @x, align 4
  tail call void @bar(i32 %0) #2
  %cmp = icmp eq i32 %c, 0
  br i1 %cmp, label %if.end, label %if.then

if.then:
  %1 = load i32, i32* @y, align 4
  tail call void @bar(i32 %1) #2
  br label %if.end

if.end:
  ret void
}

declare void @bar(i32) local_unnamed_addr