Skip to content

Commit 2b95275

Browse files
authored
[hexagon] Add support for llvm.thread.pointer (#148752)
UGP contains the pointer for thread data: > The TLS area is accessed at the processor level through the special register UGP This register is set to the address one location above the TLS area, which grows downwards from UGP. From the Hexagon ABI spec - https://docs.qualcomm.com/bundle/publicresource/80-N2040-23_REV_K_Qualcomm_Hexagon_Application_Binary_Interface_User_Guide.pdf Also: disable clang-format for `NodeType` enum in `llvm/lib/Target/Hexagon/HexagonISelLowering.h` to avoid disruptive formatting.
1 parent 6350bb3 commit 2b95275

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed

llvm/lib/Target/Hexagon/HexagonISelLowering.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,16 @@ MVT HexagonTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
236236
SDValue
237237
HexagonTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG)
238238
const {
239-
return SDValue();
239+
unsigned IntNo = Op.getConstantOperandVal(0);
240+
SDLoc dl(Op);
241+
switch (IntNo) {
242+
default:
243+
return SDValue(); // Don't custom lower most intrinsics.
244+
case Intrinsic::thread_pointer: {
245+
EVT PtrVT = getPointerTy(DAG.getDataLayout());
246+
return DAG.getNode(HexagonISD::THREAD_POINTER, dl, PtrVT);
247+
}
248+
}
240249
}
241250

242251
/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
@@ -1588,6 +1597,7 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
15881597
setOperationAction(ISD::PREFETCH, MVT::Other, Custom);
15891598
setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);
15901599
setOperationAction(ISD::READSTEADYCOUNTER, MVT::i64, Custom);
1600+
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
15911601
setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
15921602
setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
15931603
setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom);
@@ -1963,6 +1973,8 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
19631973
case HexagonISD::VROR: return "HexagonISD::VROR";
19641974
case HexagonISD::READCYCLE: return "HexagonISD::READCYCLE";
19651975
case HexagonISD::READTIMER: return "HexagonISD::READTIMER";
1976+
case HexagonISD::THREAD_POINTER:
1977+
return "HexagonISD::THREAD_POINTER";
19661978
case HexagonISD::PTRUE: return "HexagonISD::PTRUE";
19671979
case HexagonISD::PFALSE: return "HexagonISD::PFALSE";
19681980
case HexagonISD::D2P: return "HexagonISD::D2P";

llvm/lib/Target/Hexagon/HexagonISelLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace llvm {
3131

3232
namespace HexagonISD {
3333

34+
// clang-format off
3435
enum NodeType : unsigned {
3536
OP_BEGIN = ISD::BUILTIN_OP_END,
3637

@@ -78,6 +79,7 @@ enum NodeType : unsigned {
7879
DCFETCH,
7980
READCYCLE,
8081
READTIMER,
82+
THREAD_POINTER,
8183
PTRUE,
8284
PFALSE,
8385
D2P, // Convert 8-byte value to 8-bit predicate register. [*]
@@ -121,6 +123,7 @@ enum NodeType : unsigned {
121123
};
122124

123125
} // end namespace HexagonISD
126+
// clang-format on
124127

125128
class HexagonSubtarget;
126129

llvm/lib/Target/Hexagon/HexagonPatterns.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3432,6 +3432,11 @@ def HexagonREADTIMER: SDNode<"HexagonISD::READTIMER", SDTInt64Leaf,
34323432

34333433
def: Pat<(HexagonREADTIMER), (A4_tfrcpp UTIMER)>;
34343434

3435+
def SDTInt32Leaf : SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>;
3436+
def HexagonTHREADPOINTER : SDNode<"HexagonISD::THREAD_POINTER", SDTPtrLeaf>;
3437+
3438+
def : Pat<(HexagonTHREADPOINTER), (i32(COPY UGP))>;
3439+
34353440
// The declared return value of the store-locked intrinsics is i32, but
34363441
// the instructions actually define i1. To avoid register copies from
34373442
// IntRegs to PredRegs and back, fold the entire pattern checking the
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=hexagon < %s | FileCheck %s
3+
;
4+
; This test verifies the thread pointer intrinsic implementation for Hexagon.
5+
; The thread pointer (UGP register) is used to access thread-local storage.
6+
7+
declare ptr @llvm.thread.pointer() nounwind readnone
8+
9+
define ptr @thread_pointer() nounwind {
10+
; CHECK-LABEL: thread_pointer:
11+
; CHECK: // %bb.0:
12+
; CHECK: r0 = ugp
13+
; CHECK-NEXT: jumpr r31
14+
%1 = tail call ptr @llvm.thread.pointer()
15+
ret ptr %1
16+
}

0 commit comments

Comments
 (0)