-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[hexagon] Add support for llvm.thread.pointer #148752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-hexagon Author: Brian Cain (androm3da) ChangesFull diff: https://github.com/llvm/llvm-project/pull/148752.diff 4 Files Affected:
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index ec73e58ce5d44..facea646d4b68 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -236,7 +236,16 @@ MVT HexagonTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
SDValue
HexagonTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG)
const {
- return SDValue();
+ unsigned IntNo = Op.getConstantOperandVal(0);
+ SDLoc dl(Op);
+ switch (IntNo) {
+ default:
+ return SDValue(); // Don't custom lower most intrinsics.
+ case Intrinsic::thread_pointer: {
+ EVT PtrVT = getPointerTy(DAG.getDataLayout());
+ return DAG.getNode(HexagonISD::THREAD_POINTER, dl, PtrVT);
+ }
+ }
}
/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
@@ -1588,6 +1597,7 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::PREFETCH, MVT::Other, Custom);
setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);
setOperationAction(ISD::READSTEADYCOUNTER, MVT::i64, Custom);
+ setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom);
@@ -1963,6 +1973,8 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
case HexagonISD::VROR: return "HexagonISD::VROR";
case HexagonISD::READCYCLE: return "HexagonISD::READCYCLE";
case HexagonISD::READTIMER: return "HexagonISD::READTIMER";
+ case HexagonISD::THREAD_POINTER:
+ return "HexagonISD::THREAD_POINTER";
case HexagonISD::PTRUE: return "HexagonISD::PTRUE";
case HexagonISD::PFALSE: return "HexagonISD::PFALSE";
case HexagonISD::D2P: return "HexagonISD::D2P";
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index f9e5478f457f8..3d329520d097a 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -78,6 +78,7 @@ enum NodeType : unsigned {
DCFETCH,
READCYCLE,
READTIMER,
+ THREAD_POINTER,
PTRUE,
PFALSE,
D2P, // Convert 8-byte value to 8-bit predicate register. [*]
diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index 82d999ad820ed..9b072bbacdbed 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -3432,6 +3432,11 @@ def HexagonREADTIMER: SDNode<"HexagonISD::READTIMER", SDTInt64Leaf,
def: Pat<(HexagonREADTIMER), (A4_tfrcpp UTIMER)>;
+def SDTInt32Leaf : SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>;
+def HexagonTHREADPOINTER : SDNode<"HexagonISD::THREAD_POINTER", SDTInt32Leaf>;
+
+def : Pat<(HexagonTHREADPOINTER), (i32(COPY UGP))>;
+
// The declared return value of the store-locked intrinsics is i32, but
// the instructions actually define i1. To avoid register copies from
// IntRegs to PredRegs and back, fold the entire pattern checking the
diff --git a/llvm/test/CodeGen/Hexagon/thread-pointer.ll b/llvm/test/CodeGen/Hexagon/thread-pointer.ll
new file mode 100644
index 0000000000000..cebb9ff3e202d
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/thread-pointer.ll
@@ -0,0 +1,16 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=hexagon < %s | FileCheck %s
+;
+; This test verifies the thread pointer intrinsic implementation for Hexagon.
+; The thread pointer (UGP register) is used to access thread-local storage.
+
+declare ptr @llvm.thread.pointer() nounwind readnone
+
+define ptr @thread_pointer() nounwind {
+; CHECK-LABEL: thread_pointer:
+; CHECK: // %bb.0:
+; CHECK: r0 = ugp
+; CHECK-NEXT: jumpr r31
+ %1 = tail call ptr @llvm.thread.pointer()
+ ret ptr %1
+}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
I deliberately un-applied this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -3432,6 +3432,11 @@ def HexagonREADTIMER: SDNode<"HexagonISD::READTIMER", SDTInt64Leaf, | |||
|
|||
def: Pat<(HexagonREADTIMER), (A4_tfrcpp UTIMER)>; | |||
|
|||
def SDTInt32Leaf : SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>; | |||
def HexagonTHREADPOINTER : SDNode<"HexagonISD::THREAD_POINTER", SDTInt32Leaf>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should you use a ptr return type here?
def HexagonTHREADPOINTER : SDNode<"HexagonISD::THREAD_POINTER", SDTInt32Leaf>; | |
def HexagonTHREADPOINTER : SDNode<"HexagonISD::THREAD_POINTER", SDTPtrLeaf>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah thanks - good catch.
@androm3da Better to turn off clang-format for this enum |
UGP contains the pointer for thread data:
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 inllvm/lib/Target/Hexagon/HexagonISelLowering.h
to avoid disruptive formatting.