[llvm] 5e06f63 - [hexagon] Add hexagon_hvx function attribute. (#223771)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 08:02:47 PDT 2026


Author: Weiwei C
Date: 2026-10-01T15:02:27Z
New Revision: 5e06f6305d531e8d0372b45f1de4dd178051572f

URL: https://github.com/llvm/llvm-project/commit/5e06f6305d531e8d0372b45f1de4dd178051572f
DIFF: https://github.com/llvm/llvm-project/commit/5e06f6305d531e8d0372b45f1de4dd178051572f.diff

LOG: [hexagon] Add hexagon_hvx function attribute.  (#223771)

- [x] Add hexagon_hvx function attribute to be used to annotate function
that contains hand written hvx instructions.
- [x] Add logic to prevent these functions being inlined into or inline
other functions that don't have the same attributes.
- [x] Add tests.

Added: 
    llvm/test/CodeGen/Hexagon/hvx-attr-inline-compat.ll

Modified: 
    llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp b/llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp
index 3d24eb4a23b55..263eaa7ebb64f 100644
--- a/llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp
@@ -457,19 +457,14 @@ bool HexagonTTIImpl::shouldBuildLookupTables() const {
 
 bool HexagonTTIImpl::areInlineCompatible(const Function *Caller,
                                          const Function *Callee) const {
-  // The hardware provides a fixed number of HVX contexts. Software that mixes
-  // the two engines dedicates some threads to HVX, and those threads hold the
-  // contexts for as long as they run. A thread dedicated to HMX needs no
-  // context at all, until HVX code reaches it. Then it has to wait for one
-  // that the HVX threads are still holding, and if the two groups later meet
-  // at a barrier, neither side can make progress.
-  //
-  // Inlining is one way HVX code reaches a thread that was never meant to run
-  // it, in either direction: an HVX body merged into an HMX function, or an
-  // HMX body merged into a function whose other callers are HVX threads. So
-  // the attribute has to match on both sides.
+  // HVX contexts are a fixed hardware resource, held by threads dedicated to
+  // HVX. HVX reaching a thread without one stalls, and deadlocks if the two
+  // then meet at a barrier.
   if (Caller->hasFnAttribute("hexagon_hmx") !=
       Callee->hasFnAttribute("hexagon_hmx"))
     return false;
+  if (Callee->hasFnAttribute("hexagon_hvx") &&
+      !Caller->hasFnAttribute("hexagon_hvx"))
+    return false;
   return BaseT::areInlineCompatible(Caller, Callee);
 }

diff  --git a/llvm/test/CodeGen/Hexagon/hvx-attr-inline-compat.ll b/llvm/test/CodeGen/Hexagon/hvx-attr-inline-compat.ll
new file mode 100644
index 0000000000000..9561c0f694faf
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/hvx-attr-inline-compat.ll
@@ -0,0 +1,45 @@
+; A "hexagon_hvx" callee must not be inlined into a caller without the
+; attribute, in either inliner, and even when marked alwaysinline. Enforced in
+; HexagonTTIImpl::areInlineCompatible rather than through an Attributes.td
+; CompatRule, because the generic attribute check is skipped for alwaysinline
+; callees.
+
+; RUN: opt -mtriple=hexagon -passes=always-inline -S < %s | FileCheck %s
+; RUN: opt -mtriple=hexagon -passes=inline -S < %s | FileCheck %s
+
+define internal void @hvx_callee(ptr %p) alwaysinline #0 {
+  store i32 1, ptr %p, align 4
+  ret void
+}
+
+define internal void @plain_callee(ptr %p) alwaysinline #1 {
+  store i32 2, ptr %p, align 4
+  ret void
+}
+
+; The attribute 
diff ers, so the call survives.
+; CHECK-LABEL: define void @plain_caller(
+; CHECK: call void @hvx_callee(
+define void @plain_caller(ptr %p) #1 {
+  call void @hvx_callee(ptr %p)
+  ret void
+}
+
+; Both sides declared for HVX, so this inlines.
+; CHECK-LABEL: define void @hvx_caller(
+; CHECK-NOT: call void @hvx_callee(
+define void @hvx_caller(ptr %p) #0 {
+  call void @hvx_callee(ptr %p)
+  ret void
+}
+
+; The rule is one-directional: a plain callee still inlines into an HVX caller.
+; CHECK-LABEL: define void @hvx_caller_plain_callee(
+; CHECK-NOT: call void @plain_callee(
+define void @hvx_caller_plain_callee(ptr %p) #0 {
+  call void @plain_callee(ptr %p)
+  ret void
+}
+
+attributes #0 = { nounwind "hexagon_hvx" "target-features"="+hvxv68,+hvx-length128b" }
+attributes #1 = { nounwind "target-features"="+hvxv68,+hvx-length128b" }


        


More information about the llvm-commits mailing list