[llvm] r266818 - [AArch64] [ARM] Make a target-independent llvm.thread.pointer intrinsic.

Marcin Koscielnicki via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 19 13:51:05 PDT 2016


Author: koriakin
Date: Tue Apr 19 15:51:05 2016
New Revision: 266818

URL: http://llvm.org/viewvc/llvm-project?rev=266818&view=rev
Log:
[AArch64] [ARM] Make a target-independent llvm.thread.pointer intrinsic.

Both AArch64 and ARM support llvm.<arch>.thread.pointer intrinsics that
just return the thread pointer.  I have a pending patch that does the same
for SystemZ (D19054), and there are many more targets that could benefit
from one.

This patch merges the ARM and AArch64 intrinsics into a single target
independent one that will also be used by subsequent targets.

Differential Revision: http://reviews.llvm.org/D19098

Added:
    llvm/trunk/test/Assembler/autoupgrade-thread-pointer.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/IR/Intrinsics.td
    llvm/trunk/include/llvm/IR/IntrinsicsAArch64.td
    llvm/trunk/include/llvm/IR/IntrinsicsARM.td
    llvm/trunk/lib/IR/AutoUpgrade.cpp
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
    llvm/trunk/test/CodeGen/AArch64/arm64-builtins-linux.ll
    llvm/trunk/test/CodeGen/ARM/thread_pointer.ll
    llvm/trunk/test/Transforms/SafeStack/AArch64/abi.ll
    llvm/trunk/test/Transforms/SafeStack/AArch64/abi_ssp.ll

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Tue Apr 19 15:51:05 2016
@@ -9634,6 +9634,33 @@ pass will generate the appropriate data
 ``llvm.instrprof_value_profile`` intrinsic with the call to the profile
 runtime library with proper arguments.
 
+'``llvm.thread.pointer``' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+::
+
+      declare i8* @llvm.thread.pointer()
+
+Overview:
+"""""""""
+
+The '``llvm.thread.pointer``' intrinsic returns the value of the thread
+pointer.
+
+Semantics:
+""""""""""
+
+The '``llvm.thread.pointer``' intrinsic returns a pointer to the TLS area
+for the current thread.  The exact semantics of this value are target
+specific: it may point to the start of TLS area, to the end, or somewhere
+in the middle.  Depending on the target, this intrinsic may read a register,
+call a helper function, read from an alternate memory space, or perform
+other operations necessary to locate the TLS area.  Not all targets support
+this intrinsic.
+
 Standard C Library Intrinsics
 -----------------------------
 

Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Tue Apr 19 15:51:05 2016
@@ -306,6 +306,9 @@ def int_stackrestore  : Intrinsic<[], [l
 
 def int_get_dynamic_area_offset : Intrinsic<[llvm_anyint_ty]>;
 
+def int_thread_pointer : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>,
+                         GCCBuiltin<"__builtin_thread_pointer">;
+
 // IntrReadWriteArgMem is more pessimistic than strictly necessary for prefetch,
 // however it does conveniently prevent the prefetch from being reordered
 // with respect to nearby accesses to the same memory.

Modified: llvm/trunk/include/llvm/IR/IntrinsicsAArch64.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicsAArch64.td?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/IntrinsicsAArch64.td (original)
+++ llvm/trunk/include/llvm/IR/IntrinsicsAArch64.td Tue Apr 19 15:51:05 2016
@@ -13,9 +13,6 @@
 
 let TargetPrefix = "aarch64" in {
 
-def int_aarch64_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">,
-            Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
-
 def int_aarch64_ldxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty]>;
 def int_aarch64_ldaxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty]>;
 def int_aarch64_stxr : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_anyptr_ty]>;

Modified: llvm/trunk/include/llvm/IR/IntrinsicsARM.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicsARM.td?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/IntrinsicsARM.td (original)
+++ llvm/trunk/include/llvm/IR/IntrinsicsARM.td Tue Apr 19 15:51:05 2016
@@ -17,9 +17,6 @@
 
 let TargetPrefix = "arm" in {  // All intrinsics start with "llvm.arm.".
 
-def int_arm_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">,
-            Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
-
 // A space-consuming intrinsic primarily for testing ARMConstantIslands. The
 // first argument is the number of bytes this "instruction" takes up, the second
 // and return value are essentially chains, used to force ordering during ISel.

Modified: llvm/trunk/lib/IR/AutoUpgrade.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AutoUpgrade.cpp?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AutoUpgrade.cpp (original)
+++ llvm/trunk/lib/IR/AutoUpgrade.cpp Tue Apr 19 15:51:05 2016
@@ -126,6 +126,10 @@ static bool UpgradeIntrinsicFunction1(Fu
                                           StoreLaneInts[fArgs.size() - 5], Tys);
       return true;
     }
+    if (Name == "aarch64.thread.pointer" || Name == "arm.thread.pointer") {
+      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::thread_pointer);
+      return true;
+    }
     break;
   }
 
@@ -799,6 +803,12 @@ void llvm::UpgradeIntrinsicCall(CallInst
     CI->eraseFromParent();
     return;
   }
+
+  case Intrinsic::thread_pointer: {
+    CI->replaceAllUsesWith(Builder.CreateCall(NewFn, {}));
+    CI->eraseFromParent();
+    return;
+  }
   }
 }
 

Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Tue Apr 19 15:51:05 2016
@@ -2326,7 +2326,7 @@ SDValue AArch64TargetLowering::LowerINTR
   SDLoc dl(Op);
   switch (IntNo) {
   default: return SDValue();    // Don't custom lower most intrinsics.
-  case Intrinsic::aarch64_thread_pointer: {
+  case Intrinsic::thread_pointer: {
     EVT PtrVT = getPointerTy(DAG.getDataLayout());
     return DAG.getNode(AArch64ISD::THREAD_POINTER, dl, PtrVT);
   }
@@ -10265,7 +10265,7 @@ Value *AArch64TargetLowering::getIRStack
   const unsigned TlsOffset = 0x28;
   Module *M = IRB.GetInsertBlock()->getParent()->getParent();
   Function *ThreadPointerFunc =
-      Intrinsic::getDeclaration(M, Intrinsic::aarch64_thread_pointer);
+      Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
   return IRB.CreatePointerCast(
       IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), TlsOffset),
       Type::getInt8PtrTy(IRB.getContext())->getPointerTo(0));
@@ -10281,7 +10281,7 @@ Value *AArch64TargetLowering::getSafeSta
   const unsigned TlsOffset = 0x48;
   Module *M = IRB.GetInsertBlock()->getParent()->getParent();
   Function *ThreadPointerFunc =
-      Intrinsic::getDeclaration(M, Intrinsic::aarch64_thread_pointer);
+      Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
   return IRB.CreatePointerCast(
       IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), TlsOffset),
       Type::getInt8PtrTy(IRB.getContext())->getPointerTo(0));

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Apr 19 15:51:05 2016
@@ -2929,7 +2929,7 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHA
            "RBIT intrinsic must have i32 type!");
     return DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, Op.getOperand(1));
   }
-  case Intrinsic::arm_thread_pointer: {
+  case Intrinsic::thread_pointer: {
     EVT PtrVT = getPointerTy(DAG.getDataLayout());
     return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
   }

Added: llvm/trunk/test/Assembler/autoupgrade-thread-pointer.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/autoupgrade-thread-pointer.ll?rev=266818&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/autoupgrade-thread-pointer.ll (added)
+++ llvm/trunk/test/Assembler/autoupgrade-thread-pointer.ll Tue Apr 19 15:51:05 2016
@@ -0,0 +1,19 @@
+; Test autoupgrade of arch-specific thread pointer intrinsics
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+declare i8* @llvm.aarch64.thread.pointer()
+declare i8* @llvm.arm.thread.pointer()
+
+define i8* @test1() {
+; CHECK: test1()
+; CHECK: call i8* @llvm.thread.pointer()
+  %1 = call i8* @llvm.aarch64.thread.pointer()
+  ret i8 *%1
+}
+
+define i8* @test2() {
+; CHECK: test2()
+; CHECK: call i8* @llvm.thread.pointer()
+  %1 = call i8* @llvm.arm.thread.pointer()
+  ret i8 *%1
+}

Modified: llvm/trunk/test/CodeGen/AArch64/arm64-builtins-linux.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-builtins-linux.ll?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/arm64-builtins-linux.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/arm64-builtins-linux.ll Tue Apr 19 15:51:05 2016
@@ -1,11 +1,11 @@
 ; RUN: llc < %s -march=aarch64 -mtriple=aarch64-linux-gnu | FileCheck %s
 
 ; Function Attrs: nounwind readnone
-declare i8* @llvm.aarch64.thread.pointer() #1
+declare i8* @llvm.thread.pointer() #1
 
 define i8* @thread_pointer() {
 ; CHECK: thread_pointer:
 ; CHECK: mrs {{x[0-9]+}}, TPIDR_EL0
-  %1 = tail call i8* @llvm.aarch64.thread.pointer()
+  %1 = tail call i8* @llvm.thread.pointer()
   ret i8* %1
 }

Modified: llvm/trunk/test/CodeGen/ARM/thread_pointer.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/thread_pointer.ll?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/thread_pointer.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/thread_pointer.ll Tue Apr 19 15:51:05 2016
@@ -3,8 +3,8 @@
 
 define i8* @test() {
 entry:
-	%tmp1 = call i8* @llvm.arm.thread.pointer( )		; <i8*> [#uses=0]
+	%tmp1 = call i8* @llvm.thread.pointer( )		; <i8*> [#uses=0]
 	ret i8* %tmp1
 }
 
-declare i8* @llvm.arm.thread.pointer()
+declare i8* @llvm.thread.pointer()

Modified: llvm/trunk/test/Transforms/SafeStack/AArch64/abi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SafeStack/AArch64/abi.ll?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SafeStack/AArch64/abi.ll (original)
+++ llvm/trunk/test/Transforms/SafeStack/AArch64/abi.ll Tue Apr 19 15:51:05 2016
@@ -3,7 +3,7 @@
 
 define void @foo() nounwind uwtable safestack {
 entry:
-; CHECK: %[[TP:.*]] = call i8* @llvm.aarch64.thread.pointer()
+; CHECK: %[[TP:.*]] = call i8* @llvm.thread.pointer()
 ; CHECK: %[[SPA0:.*]] = getelementptr i8, i8* %[[TP]], i32 72
 ; CHECK: %[[SPA:.*]] = bitcast i8* %[[SPA0]] to i8**
 ; CHECK: %[[USP:.*]] = load i8*, i8** %[[SPA]]

Modified: llvm/trunk/test/Transforms/SafeStack/AArch64/abi_ssp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SafeStack/AArch64/abi_ssp.ll?rev=266818&r1=266817&r2=266818&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SafeStack/AArch64/abi_ssp.ll (original)
+++ llvm/trunk/test/Transforms/SafeStack/AArch64/abi_ssp.ll Tue Apr 19 15:51:05 2016
@@ -3,10 +3,10 @@
 
 define void @foo() nounwind uwtable safestack sspreq {
 entry:
-; The first @llvm.aarch64.thread.pointer is for the unsafe stack pointer, skip it.
-; TLS: call i8* @llvm.aarch64.thread.pointer()
+; The first @llvm.thread.pointer is for the unsafe stack pointer, skip it.
+; TLS: call i8* @llvm.thread.pointer()
 
-; TLS: %[[TP2:.*]] = call i8* @llvm.aarch64.thread.pointer()
+; TLS: %[[TP2:.*]] = call i8* @llvm.thread.pointer()
 ; TLS: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 40
 ; TLS: %[[C:.*]] = bitcast i8* %[[B]] to i8**
 ; TLS: %[[StackGuard:.*]] = load i8*, i8** %[[C]]




More information about the llvm-commits mailing list