aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2024-04-19 10:01:42 -0700
committerGitHub <noreply@github.com>2024-04-19 10:01:42 -0700
commit6bbccd2516c3a843809a8303da48abce58a88855 (patch)
treefb5c5666a20155ecc03c688671f02609a73225a7
parent41e696291c64fe19629e14887ed1ed9b9c2271f0 (diff)
downloadllvm-6bbccd2516c3a843809a8303da48abce58a88855.zip
llvm-6bbccd2516c3a843809a8303da48abce58a88855.tar.gz
llvm-6bbccd2516c3a843809a8303da48abce58a88855.tar.bz2
GlobalsModRef, ValueTracking: Look through threadlocal.address intrinsic (#88418)
This improves handling of `threadlocal.address` intrinsic in analyses: The thread-id cannot change within a function with the exception of suspend points of pre-split coroutines. This changes `llvm::getUnderlyingObject` to look through `threadlocal.address` in these cases. `GlobalsAAResult::AnalyzeUsesOfPointer` checks whether an address can be traced to simple loads/stores or escapes to other places. Starting the analysis from a thread-local `GlobalValue` the `threadlocal.address` intrinsic is safe to skip here. This improves issue #87437
-rw-r--r--llvm/include/llvm/Analysis/ValueTracking.h10
-rw-r--r--llvm/lib/Analysis/GlobalsModRef.cpp8
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp4
-rw-r--r--llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll61
-rw-r--r--llvm/test/CodeGen/PowerPC/aix-small-local-dynamic-tls-largeaccess.ll60
-rw-r--r--llvm/test/CodeGen/PowerPC/aix-small-local-exec-tls-largeaccess.ll44
-rw-r--r--llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-funcattr.ll6
-rw-r--r--llvm/test/CodeGen/X86/threadlocal_address.ll4
8 files changed, 135 insertions, 62 deletions
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index e1c41b3..bab7c88 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -690,11 +690,11 @@ inline Value *getArgumentAliasingToReturnedPointer(CallBase *Call,
bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(
const CallBase *Call, bool MustPreserveNullness);
-/// This method strips off any GEP address adjustments and pointer casts from
-/// the specified value, returning the original object being addressed. Note
-/// that the returned value has pointer type if the specified value does. If
-/// the MaxLookup value is non-zero, it limits the number of instructions to
-/// be stripped off.
+/// This method strips off any GEP address adjustments, pointer casts
+/// or `llvm.threadlocal.address` from the specified value \p V, returning the
+/// original object being addressed. Note that the returned value has pointer
+/// type if the specified value does. If the \p MaxLookup value is non-zero, it
+/// limits the number of instructions to be stripped off.
const Value *getUnderlyingObject(const Value *V, unsigned MaxLookup = 6);
inline Value *getUnderlyingObject(Value *V, unsigned MaxLookup = 6) {
// Force const to avoid infinite recursion.
diff --git a/llvm/lib/Analysis/GlobalsModRef.cpp b/llvm/lib/Analysis/GlobalsModRef.cpp
index 527f19b..1ceb1b2 100644
--- a/llvm/lib/Analysis/GlobalsModRef.cpp
+++ b/llvm/lib/Analysis/GlobalsModRef.cpp
@@ -344,6 +344,14 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
if (AnalyzeUsesOfPointer(I, Readers, Writers, OkayStoreDest))
return true;
} else if (auto *Call = dyn_cast<CallBase>(I)) {
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
+ if (II->getIntrinsicID() == Intrinsic::threadlocal_address &&
+ V == II->getArgOperand(0)) {
+ if (AnalyzeUsesOfPointer(II, Readers, Writers))
+ return true;
+ continue;
+ }
+ }
// Make sure that this is just the function being called, not that it is
// passing into the function.
if (Call->isDataOperand(&U)) {
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index b87bba7..c038f7e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6255,6 +6255,10 @@ bool llvm::isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(
return true;
case Intrinsic::ptrmask:
return !MustPreserveNullness;
+ case Intrinsic::threadlocal_address:
+ // The underlying variable changes with thread ID. The Thread ID may change
+ // at coroutine suspend points.
+ return !Call->getParent()->getParent()->isPresplitCoroutine();
default:
return false;
}
diff --git a/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll b/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
index d109b3b..24ad14b 100644
--- a/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
+++ b/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
@@ -22,6 +22,67 @@ entry:
ret i32 %v
}
+@g1_tls = internal thread_local global i32 0
+
+define i32 @test1_tls(ptr %param) {
+; Ensure that we can fold a store to a load of a global across a store to
+; a parameter when the global is non-escaping.
+;
+; CHECK-LABEL: define i32 @test1_tls(
+; CHECK-SAME: ptr [[PARAM:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[P:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @g1_tls)
+; CHECK-NEXT: store i32 42, ptr [[P]], align 4
+; CHECK-NEXT: store i32 7, ptr [[PARAM]], align 4
+; CHECK-NEXT: ret i32 42
+;
+entry:
+ %p = call ptr @llvm.threadlocal.address(ptr @g1_tls)
+ store i32 42, ptr %p
+ store i32 7, ptr %param
+ %p2 = call ptr @llvm.threadlocal.address(ptr @g1_tls)
+ %v = load i32, ptr %p2
+ ret i32 %v
+}
+
+define ptr @test1_tls_noopt(ptr %coro, ptr %param) presplitcoroutine {
+; CHECK-LABEL: define ptr @test1_tls_noopt(
+; CHECK-SAME: ptr [[CORO:%.*]], ptr [[PARAM:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[P:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @g1_tls)
+; CHECK-NEXT: store i32 42, ptr [[P]], align 4
+; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.coro.suspend(token none, i1 false)
+; CHECK-NEXT: switch i8 [[TMP0]], label [[SUSPEND:%.*]] [
+; CHECK-NEXT: i8 0, label [[RESUME:%.*]]
+; CHECK-NEXT: i8 1, label [[SUSPEND]]
+; CHECK-NEXT: ]
+; CHECK: resume:
+; CHECK-NEXT: [[P2:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @g1_tls)
+; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P2]], align 4
+; CHECK-NEXT: store i32 [[V]], ptr [[PARAM]], align 4
+; CHECK-NEXT: ret ptr [[CORO]]
+; CHECK: suspend:
+; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.coro.end(ptr [[CORO]], i1 false, token none)
+; CHECK-NEXT: ret ptr [[CORO]]
+;
+entry:
+ %p = call ptr @llvm.threadlocal.address(ptr @g1_tls)
+ store i32 42, ptr %p
+
+ %0 = call i8 @llvm.coro.suspend(token none, i1 false)
+ switch i8 %0, label %suspend [i8 0, label %resume
+ i8 1, label %suspend]
+resume:
+ %p2 = call ptr @llvm.threadlocal.address(ptr @g1_tls)
+ %v = load i32, ptr %p2
+ store i32 %v, ptr %param, align 4
+ ret ptr %coro
+
+suspend:
+ call i1 @llvm.coro.end(ptr %coro, i1 0)
+ ret ptr %coro
+}
+
declare ptr @f()
define i32 @test2() {
diff --git a/llvm/test/CodeGen/PowerPC/aix-small-local-dynamic-tls-largeaccess.ll b/llvm/test/CodeGen/PowerPC/aix-small-local-dynamic-tls-largeaccess.ll
index 7db1048..d3fa947 100644
--- a/llvm/test/CodeGen/PowerPC/aix-small-local-dynamic-tls-largeaccess.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-small-local-dynamic-tls-largeaccess.ll
@@ -229,24 +229,24 @@ define signext i32 @test3() {
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: mflr r0
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stdu r1, -48(r1)
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: ld r8, L..C3(r2) # target-flags(ppc-tlsld) @ElementIntTLSv2
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: std r0, 64(r1)
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: li r6, 2
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: bla .__tls_get_mod[PR]
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: li r4, 1
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: la r5, ElementIntTLS2[TL]@ld(r3)
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: la r6, ElementIntTLS3[TL]@ld(r3)
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: la r7, ElementIntTLS4[TL]@ld(r3)
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: la r9, ElementIntTLS5[TL]@ld(r3)
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stwux r4, r3, r8
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: la r7, ElementIntTLS3[TL]@ld(r3)
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stw r6, 320(r5)
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: li r5, 3
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: la r6, ElementIntTLS4[TL]@ld(r3)
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stw r5, 324(r7)
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: ld r5, L..C3(r2) # target-flags(ppc-tlsld) @ElementIntTLSv2
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: la r7, ElementIntTLS5[TL]@ld(r3)
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stwux r4, r3, r5
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: li r4, 4
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stw r4, 24(r3)
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: li r3, 2
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stw r3, 320(r5)
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: li r3, 3
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stw r3, 324(r6)
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: li r3, 88
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stw r4, 328(r7)
-; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stw r3, 332(r9)
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stw r4, 328(r6)
+; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: stw r3, 332(r7)
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: li r3, 102
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: addi r1, r1, 48
; SMALL-LOCAL-DYNAMIC-SMALLCM64-NEXT: ld r0, 16(r1)
@@ -258,26 +258,26 @@ define signext i32 @test3() {
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: mflr r0
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stdu r1, -48(r1)
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: addis r3, L..C0@u(r2)
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: addis r6, L..C3@u(r2)
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: std r0, 64(r1)
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: addis r6, L..C3@u(r2)
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: ld r3, L..C0@l(r3)
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: ld r6, L..C3@l(r6)
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: li r7, 3
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: bla .__tls_get_mod[PR]
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: li r5, 2
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: la r4, ElementIntTLS2[TL]@ld(r3)
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stw r5, 320(r4)
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: li r4, 1
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: la r5, ElementIntTLS2[TL]@ld(r3)
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: la r7, ElementIntTLS3[TL]@ld(r3)
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: la r8, ElementIntTLS4[TL]@ld(r3)
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: la r9, ElementIntTLS5[TL]@ld(r3)
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: la r5, ElementIntTLS3[TL]@ld(r3)
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stw r7, 324(r5)
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: la r5, ElementIntTLS4[TL]@ld(r3)
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: la r7, ElementIntTLS5[TL]@ld(r3)
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stwux r4, r3, r6
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: li r4, 4
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stw r4, 24(r3)
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: li r3, 2
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stw r3, 320(r5)
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: li r3, 3
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stw r3, 324(r7)
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: li r3, 88
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stw r4, 328(r8)
-; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stw r3, 332(r9)
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stw r4, 328(r5)
+; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: stw r3, 332(r7)
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: li r3, 102
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: addi r1, r1, 48
; SMALL-LOCAL-DYNAMIC-LARGECM64-NEXT: ld r0, 16(r1)
@@ -351,12 +351,12 @@ entry:
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 9, 3, 9
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 6, 3, 6
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stwux 4, 3, 5
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 2
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 320(6)
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 3
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 324(7)
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 4
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 24(3)
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 2
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, 320(6)
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 3
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, 324(7)
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 88
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 328(8)
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, 332(9)
@@ -466,12 +466,12 @@ entry:
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 9, 3, 9
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 6, 3, 6
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stwux 4, 3, 5
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 2
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 320(6)
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 3
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 324(7)
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 4
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 24(3)
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 2
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, 320(6)
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 3
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, 324(7)
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 88
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 328(8)
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, 332(9)
diff --git a/llvm/test/CodeGen/PowerPC/aix-small-local-exec-tls-largeaccess.ll b/llvm/test/CodeGen/PowerPC/aix-small-local-exec-tls-largeaccess.ll
index 67d82c6..91013af 100644
--- a/llvm/test/CodeGen/PowerPC/aix-small-local-exec-tls-largeaccess.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-small-local-exec-tls-largeaccess.ll
@@ -30,11 +30,11 @@ define signext i32 @StoreArrays1() {
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r3, mySmallLocalExecTLSv1[TL]@le(r13)
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r3, 2
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r4, mySmallLocalExecTLSv1[TL]@le+24(r13)
+; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r4, (mySmallLocalExecTLS4[TL]@le+328)-65536(r13)
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r3, (mySmallLocalExecTLS2[TL]@le+320)-65536(r13)
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r3, 3
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r3, (mySmallLocalExecTLS3[TL]@le+324)-65536(r13)
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r3, 88
-; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r4, (mySmallLocalExecTLS4[TL]@le+328)-65536(r13)
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r3, (mySmallLocalExecTLS5[TL]@le+332)-65536(r13)
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r3, 102
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: blr
@@ -46,11 +46,11 @@ define signext i32 @StoreArrays1() {
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r3, mySmallLocalExecTLSv1[TL]@le(r13)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r3, 2
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r4, mySmallLocalExecTLSv1[TL]@le+24(r13)
+; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r4, (mySmallLocalExecTLS4[TL]@le+328)-65536(r13)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r3, (mySmallLocalExecTLS2[TL]@le+320)-65536(r13)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r3, 3
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r3, (mySmallLocalExecTLS3[TL]@le+324)-65536(r13)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r3, 88
-; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r4, (mySmallLocalExecTLS4[TL]@le+328)-65536(r13)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r3, (mySmallLocalExecTLS5[TL]@le+332)-65536(r13)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r3, 102
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: blr
@@ -88,16 +88,16 @@ entry:
define signext i32 @StoreArrays2() {
; SMALL-LOCAL-EXEC-SMALLCM64-LABEL: StoreArrays2:
; SMALL-LOCAL-EXEC-SMALLCM64: # %bb.0: # %entry
-; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: ld r4, L..C0(r2) # target-flags(ppc-tprel) @mySmallLocalExecTLSv2
+; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r4, 2
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r3, 1
+; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r4, (mySmallLocalExecTLS2[TL]@le+320)-65536(r13)
+; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r4, 3
+; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r4, (mySmallLocalExecTLS3[TL]@le+324)-65536(r13)
+; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: ld r4, L..C0(r2) # target-flags(ppc-tprel) @mySmallLocalExecTLSv2
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: add r4, r13, r4
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r3, 0(r4)
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r3, 4
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r3, 24(r4)
-; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r4, 2
-; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r4, (mySmallLocalExecTLS2[TL]@le+320)-65536(r13)
-; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r4, 3
-; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r4, (mySmallLocalExecTLS3[TL]@le+324)-65536(r13)
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r4, 88
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: stw r3, (mySmallLocalExecTLS4[TL]@le+328)-65536(r13)
; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r3, 102
@@ -106,17 +106,17 @@ define signext i32 @StoreArrays2() {
;
; SMALL-LOCAL-EXEC-LARGECM64-LABEL: StoreArrays2:
; SMALL-LOCAL-EXEC-LARGECM64: # %bb.0: # %entry
+; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r3, 2
+; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r4, 3
+; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r3, (mySmallLocalExecTLS2[TL]@le+320)-65536(r13)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: addis r3, L..C0@u(r2)
-; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r4, 1
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: ld r3, L..C0@l(r3)
+; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r4, (mySmallLocalExecTLS3[TL]@le+324)-65536(r13)
+; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r4, 1
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: add r3, r13, r3
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r4, 0(r3)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r4, 4
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r4, 24(r3)
-; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r3, 2
-; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r3, (mySmallLocalExecTLS2[TL]@le+320)-65536(r13)
-; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r3, 3
-; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r3, (mySmallLocalExecTLS3[TL]@le+324)-65536(r13)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r3, 88
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r4, (mySmallLocalExecTLS4[TL]@le+328)-65536(r13)
; SMALL-LOCAL-EXEC-LARGECM64-NEXT: stw r3, (mySmallLocalExecTLS5[TL]@le+332)-65536(r13)
@@ -162,35 +162,35 @@ entry:
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 2
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 24(13)
; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+15]]) mySmallLocalExecTLSv1[TL]
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, -460(13)
+; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+21]]) mySmallLocalExecTLS4[TL]
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, -32468(13)
; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+17]]) mySmallLocalExecTLS2[TL]
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 3
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, -16464(13)
; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+19]]) mySmallLocalExecTLS3[TL]
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 88
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, -460(13)
-; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+21]]) mySmallLocalExecTLS4[TL]
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, 15544(13)
; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+23]]) mySmallLocalExecTLS5[TL]
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 102
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} blr
; DIS: 0000000000000040 (idx: [[#NFA+5]]) .StoreArrays2:
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 2
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 3
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, -32468(13)
+; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+17]]) mySmallLocalExecTLS2[TL]
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} addis 3, 2, 0
; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOCU (idx: [[#NFA+13]]) mySmallLocalExecTLSv2[TE]
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 1
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} ld 3, 0(3)
; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOCL (idx: [[#NFA+13]]) mySmallLocalExecTLSv2[TE]
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, -16464(13)
+; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+19]]) mySmallLocalExecTLS3[TL]
+; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 1
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 3, 13, 3
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 0(3)
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 4, 4
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, 24(3)
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 2
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, -32468(13)
-; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+17]]) mySmallLocalExecTLS2[TL]
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 3
-; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, -16464(13)
-; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+19]]) mySmallLocalExecTLS3[TL]
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} li 3, 88
; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 4, -460(13)
; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TLS_LE (idx: [[#NFA+21]]) mySmallLocalExecTLS4[TL]
@@ -227,4 +227,4 @@ entry:
; DIS: 000000000000be6c (idx: [[#NFA+19]]) mySmallLocalExecTLS3[TL]:
; DIS: 000000000000fcec (idx: [[#NFA+21]]) mySmallLocalExecTLS4[TL]:
; DIS: 0000000000013b6c (idx: [[#NFA+23]]) mySmallLocalExecTLS5[TL]:
-; DIS: 00000000000179ec (idx: [[#NFA+25]]) mySmallLocalExecTLSv2[TL]: \ No newline at end of file
+; DIS: 00000000000179ec (idx: [[#NFA+25]]) mySmallLocalExecTLSv2[TL]:
diff --git a/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-funcattr.ll b/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-funcattr.ll
index 38b35dc..91a2283 100644
--- a/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-funcattr.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-funcattr.ll
@@ -64,9 +64,9 @@ define i64 @StoreLargeAccess2() {
; CHECK-SMALLCM64-NEXT: li r3, 55
; CHECK-SMALLCM64-NEXT: li r4, 64
; CHECK-SMALLCM64-NEXT: std r3, mySmallTLS2[TL]@le+696(r13)
+; CHECK-SMALLCM64-NEXT: add r3, r13, r5
+; CHECK-SMALLCM64-NEXT: std r4, 20000(r3)
; CHECK-SMALLCM64-NEXT: li r3, 142
-; CHECK-SMALLCM64-NEXT: add r5, r13, r5
-; CHECK-SMALLCM64-NEXT: std r4, 20000(r5)
; CHECK-LARGECM64: addis r3, L..C0@u(r2)
; CHECK-LARGECM64-NEXT: li r4, 0
; CHECK-LARGECM64-NEXT: li r5, 23
@@ -75,8 +75,8 @@ define i64 @StoreLargeAccess2() {
; CHECK-LARGECM64-NEXT: add r3, r13, r3
; CHECK-LARGECM64-NEXT: stdx r5, r3, r4
; CHECK-LARGECM64-NEXT: addis r3, L..C1@u(r2)
-; CHECK-LARGECM64-NEXT: li r4, 55
; CHECK-LARGECM64-NEXT: li r5, 64
+; CHECK-LARGECM64-NEXT: li r4, 55
; CHECK-LARGECM64-NEXT: ld r3, L..C1@l(r3)
; CHECK-LARGECM64-NEXT: std r4, mySmallTLS2[TL]@le+696(r13)
; CHECK-LARGECM64-NEXT: add r3, r13, r3
diff --git a/llvm/test/CodeGen/X86/threadlocal_address.ll b/llvm/test/CodeGen/X86/threadlocal_address.ll
index 6c6649b..52ff413 100644
--- a/llvm/test/CodeGen/X86/threadlocal_address.ll
+++ b/llvm/test/CodeGen/X86/threadlocal_address.ll
@@ -4,7 +4,7 @@
define noundef i32 @foo() {
; CHECK: %0:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gottpoff) @i, $noreg :: (load (s64) from got)
-; CHECK: %1:gr32 = MOV32rm %0, 1, $noreg, 0, $fs :: (load (s32) from %ir.0)
+; CHECK: %1:gr32 = MOV32rm %0, 1, $noreg, 0, $fs :: (dereferenceable load (s32) from %ir.0)
; CHECK: %2:gr32 = nsw INC32r %1, implicit-def dead $eflags
; CHECK: MOV32mr %0, 1, $noreg, 0, $fs, %2 :: (store (s32) into %ir.0)
; CHECK: $eax = COPY %2
@@ -22,7 +22,7 @@ entry:
@j = thread_local addrspace(1) global ptr addrspace(0) @i, align 4
define noundef i32 @bar() {
; CHECK: %0:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gottpoff) @j, $noreg :: (load (s64) from got)
-; CHECK: %1:gr32 = MOV32rm %0, 1, $noreg, 0, $fs :: (load (s32) from %ir.0, addrspace 1)
+; CHECK: %1:gr32 = MOV32rm %0, 1, $noreg, 0, $fs :: (dereferenceable load (s32) from %ir.0, addrspace 1)
; CHECK: %2:gr32 = nsw INC32r %1, implicit-def dead $eflags
; CHECK: MOV32mr %0, 1, $noreg, 0, $fs, %2 :: (store (s32) into %ir.0, addrspace 1)
; CHECK: $eax = COPY %2