Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -17818,6 +17818,17 @@ Reg = RegInfo->getPtrSizedFrameRegister(MF); return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT); } + + case Intrinsic::thread_pointer: { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + EVT PtrVT = TLI.getPointerTy(DAG.getDataLayout()); + // Get the Thread Pointer, which is %gs:0 (32-bit) or %fs:0 (64-bit). + Value *Ptr = Constant::getNullValue( + Type::getInt8PtrTy(*DAG.getContext(), Subtarget.is64Bit() ? 257 : 256)); + return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), + DAG.getIntPtrConstant(0, dl), + MachinePointerInfo(Ptr), false, false, false, 0); + } } } Index: test/CodeGen/X86/thread-pointer.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/thread-pointer.ll @@ -0,0 +1,12 @@ +; RUN: llc < %s -mtriple=i386-unknown-linux | FileCheck %s --check-prefix=CHECK-32 +; RUN: llc < %s -mtriple=x86_64-unknown-linux | FileCheck %s --check-prefix=CHECK-64 + +; Function Attrs: nounwind readnone +declare i8* @llvm.thread.pointer() #1 + +define i8* @thread_pointer() { +; CHECK-32: movl %gs:0, %eax +; CHECK-64: movq %fs:0, %rax + %1 = tail call i8* @llvm.thread.pointer() + ret i8* %1 +}