[llvm] [HLSL] Add in-memory representation of Semantic Signatures (PR #209907)
Justin Bogner via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 28 22:00:11 PDT 2026
================
@@ -0,0 +1,202 @@
+//===- SemanticSignatures.cpp - HLSL Semantic Signature helpers -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file This file implements a library for working with HLSL shader input and
+/// output semantic signatures and their DirectX metadata representation.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Frontend/HLSL/SemanticSignatures.h"
+#include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Type.h"
+
+using namespace llvm;
+using namespace llvm::hlsl;
+
+namespace {
+
+// Inclusive upper bounds of the operand enums
+constexpr uint32_t MaxCompType =
+ static_cast<uint32_t>(dxil::ElementType::PackedU8x32);
+constexpr uint32_t MaxSemanticKind =
+ static_cast<uint32_t>(dxbc::PSV::SemanticKind::Invalid);
+constexpr uint32_t MaxInterpMode =
+ static_cast<uint32_t>(dxbc::PSV::InterpolationMode::Invalid);
+
+Error makeError(const Twine &Msg) {
+ return createStringError(inconvertibleErrorCode(), Msg);
+}
+
+Expected<uint64_t> extractInt(const MDNode *Node, unsigned OpId) {
+ auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(Node->getOperand(OpId));
+ if (!CI)
+ return makeError("expected integer operand " + Twine(OpId));
+ return CI->getZExtValue();
+}
+} // namespace
+
+Expected<SemanticSignatureElement>
+SemanticSignatureElement::fromMetadata(const MDNode *Node) {
+ // Operand positions within a signature element metadata node.
+ enum class OpIdx : unsigned {
+ SigId,
+ SemanticName,
+ CompType,
+ SemanticKind,
+ SemanticIndices,
+ InterpMode,
+ Rows,
+ Cols,
+ StartRow,
+ StartCol,
+ UsageMask,
+ DynIndexMask,
+ GSStream,
+ NumOperands,
+ };
+ const unsigned NumElementOperands = to_underlying(OpIdx::NumOperands);
----------------
bogner wrote:
It doesn't really matter here because we never switch over the enum, but it's generally better to use a `LastEntry` to a `NumXYZ` for this kind of reflection in an enum, to avoid having an extra value that you need to deal with.
https://github.com/llvm/llvm-project/pull/209907
More information about the llvm-commits
mailing list