Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp @@ -7715,6 +7715,16 @@ /// lower, do it, otherwise return null. SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { + unsigned IntrinsicID = + cast(Op.getOperand(0))->getZExtValue(); + + if (IntrinsicID == Intrinsic::thread_pointer) { + // Reads the thread pointer register, used for __builtin_thread_pointer. + bool is64bit = Subtarget.isPPC64(); + return DAG.getRegister(is64bit ? PPC::X13 : PPC::R2, + is64bit ? MVT::i64 : MVT::i32); + } + // If this is a lowered altivec predicate compare, CompareOpc is set to the // opcode number of the comparison. SDLoc dl(Op); Index: llvm/trunk/test/CodeGen/PowerPC/thread-pointer.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/thread-pointer.ll +++ llvm/trunk/test/CodeGen/PowerPC/thread-pointer.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu | FileCheck %s --check-prefix=CHECK-32 +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s --check-prefix=CHECK-64 +; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s --check-prefix=CHECK-64 + +; Function Attrs: nounwind readnone +declare i8* @llvm.thread.pointer() #1 + +define i8* @thread_pointer() { +; CHECK-32-LABEL: @thread_pointer +; CHECK-32: mr 3, 2 +; CHECK-32: blr +; CHECK-64-LABEL: @thread_pointer +; CHECK-64: mr 3, 13 +; CHECK-64: blr + %1 = tail call i8* @llvm.thread.pointer() + ret i8* %1 +}