[llvm] [Hexagon] Add new register input/output types for qf instructions (PR #184398)

Fateme Hosseini via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 3 09:56:15 PST 2026


https://github.com/fhossein-quic created https://github.com/llvm/llvm-project/pull/184398

The v81 iset has been updated with input and output register
types/extensions for instructions. Currently, it supports qf32/qf16
register types. This patch implements a qf reg type lookup to query
these types. In the future, the register type extractor can be improved
and more APIs can be added to support other register types.

Co-authored-by: <santdas at qti.qualcomm.com>

>From bdba59e7b13bed9e9260b7f59f467ac5148bc9ff Mon Sep 17 00:00:00 2001
From: Fateme Hosseini <fhossein at qti.qualcomm.com>
Date: Mon, 2 Mar 2026 12:58:47 -0800
Subject: [PATCH 1/2] [Hexagon] Add qf reg type query APIs

Add RegType/RegTypeInfo plumbing and new HexagonInstrInfo query helpers for qf16/qf32 operand/result types.

Change-Id: I6afecf52ceeaf87b6c27968490c2a702d6e288ab
---
 llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp  | 52 +++++++++++++++++++
 llvm/lib/Target/Hexagon/HexagonInstrInfo.h    | 11 ++++
 .../Hexagon/MCTargetDesc/HexagonBaseInfo.h    | 32 ++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index 9f511efdfb461..258e540d6bc0c 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -4783,6 +4783,58 @@ bool HexagonInstrInfo::isQFPMul(const MachineInstr *MI) const {
           MI->getOpcode() == Hexagon::V6_vmpy_qf32);
 }
 
+bool HexagonInstrInfo::usesQF32Operand(MachineInstr *MI, unsigned Index) const {
+  auto Info = HexagonII::getRegTypeInfo(MI->getOpcode());
+  switch (Index) {
+  case 1:
+    return Info.Input1 == HexagonII::RegType::QF32;
+  case 2:
+    return Info.Input2 == HexagonII::RegType::QF32;
+  case 3:
+    return Info.Input3 == HexagonII::RegType::QF32;
+  case 0:
+    return Info.Input1 == HexagonII::RegType::QF32 ||
+           Info.Input2 == HexagonII::RegType::QF32 ||
+           Info.Input3 == HexagonII::RegType::QF32;
+  default:
+    llvm_unreachable("Incorrect input machine operand index encountered!");
+  }
+}
+
+bool HexagonInstrInfo::usesQF16Operand(MachineInstr *MI, unsigned Index) const {
+  auto Info = HexagonII::getRegTypeInfo(MI->getOpcode());
+  switch (Index) {
+  case 1:
+    return Info.Input1 == HexagonII::RegType::QF16;
+  case 2:
+    return Info.Input2 == HexagonII::RegType::QF16;
+  case 3:
+    return Info.Input3 == HexagonII::RegType::QF16;
+  case 0:
+    return Info.Input1 == HexagonII::RegType::QF16 ||
+           Info.Input2 == HexagonII::RegType::QF16 ||
+           Info.Input3 == HexagonII::RegType::QF16;
+  default:
+    llvm_unreachable("Incorrect input machine operand index encountered!");
+  }
+}
+
+bool HexagonInstrInfo::usesQFOperand(MachineInstr *MI, unsigned Index) const {
+  return usesQF32Operand(MI, Index) || usesQF16Operand(MI, Index);
+}
+
+bool HexagonInstrInfo::isQFP32Instr(MachineInstr *MI) const {
+  return HexagonII::getOpRegType(MI->getOpcode()) == HexagonII::RegType::QF32;
+}
+
+bool HexagonInstrInfo::isQFP16Instr(MachineInstr *MI) const {
+  return HexagonII::getOpRegType(MI->getOpcode()) == HexagonII::RegType::QF16;
+}
+
+bool HexagonInstrInfo::isQFPInstr(MachineInstr *MI) const {
+  return isQFP32Instr(MI) || isQFP16Instr(MI);
+}
+
 // Addressing mode relations.
 short HexagonInstrInfo::changeAddrMode_abs_io(short Opc) const {
   return Opc >= 0 ? Hexagon::changeAddrMode_abs_io(Opc) : Opc;
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h
index 4535fd6b71ef6..230f5d2228457 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h
@@ -540,6 +540,17 @@ class HexagonInstrInfo : public HexagonGenInstrInfo {
 
   MCInst getNop() const override;
   bool isQFPMul(const MachineInstr *MF) const;
+
+  // Check if the instruction uses a qf32/qf16 operand.
+  // 'Index' specifies the input operand number (1..3). If 0, check any.
+  bool usesQF32Operand(MachineInstr *MI, unsigned Index = 0) const;
+  bool usesQF16Operand(MachineInstr *MI, unsigned Index = 0) const;
+  bool usesQFOperand(MachineInstr *MI, unsigned Index = 0) const;
+
+  // Check if the instruction has a qf32/qf16 output.
+  bool isQFP32Instr(MachineInstr *MI) const;
+  bool isQFP16Instr(MachineInstr *MI) const;
+  bool isQFPInstr(MachineInstr *MI) const;
 };
 
 /// \brief Create RegSubRegPair from a register MachineOperand
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
index e3094b4438e5f..995b7bb1f245e 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
@@ -16,6 +16,8 @@
 #ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONBASEINFO_H
 #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONBASEINFO_H
 
+#include <cstdint>
+
 #include "HexagonDepITypes.h"
 #include "MCTargetDesc/HexagonMCTargetDesc.h"
 
@@ -46,6 +48,36 @@ namespace HexagonII {
     HVXVectorAccess
   };
 
+  // Represents additional operand/result register type constraints attached to
+  // specific instructions (e.g. QF register types).
+  enum class RegType : uint8_t {
+    Unknown = 0,
+    QF32,
+    QF16,
+  };
+
+  struct RegTypeInfo {
+    RegType Output = RegType::Unknown;
+    RegType Input1 = RegType::Unknown;
+    RegType Input2 = RegType::Unknown;
+    RegType Input3 = RegType::Unknown;
+  };
+
+  inline RegTypeInfo getRegTypeInfo(unsigned /*Opcode*/) { return {}; }
+
+  inline RegType getOpRegType(unsigned Opcode) {
+    return getRegTypeInfo(Opcode).Output;
+  }
+  inline RegType getInp1RegType(unsigned Opcode) {
+    return getRegTypeInfo(Opcode).Input1;
+  }
+  inline RegType getInp2RegType(unsigned Opcode) {
+    return getRegTypeInfo(Opcode).Input2;
+  }
+  inline RegType getInp3RegType(unsigned Opcode) {
+    return getRegTypeInfo(Opcode).Input3;
+  }
+
   // MCInstrDesc TSFlags
   // *** Must match HexagonInstrFormat*.td ***
   enum {

>From 085ff870187d6b81f13e5bda2941fe9cf382c961 Mon Sep 17 00:00:00 2001
From: Fateme Hosseini <fhossein at qti.qualcomm.com>
Date: Mon, 2 Mar 2026 14:44:06 -0800
Subject: [PATCH 2/2] [Hexagon] Add new register input/output types for qf
 instructions

The v81 iset has been updated with input and output register
types/extensions for instructions. Currently, it supports qf32/qf16
register types. This patch implements a qf reg type lookup to query
these types. In the future, the register type extractor can be improved
and more APIs can be added to support other register types.

Co-authored-by: <santdas at qti.qualcomm.com>
---
 llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp  | 114 ++++++++++++++++++
 .../Hexagon/MCTargetDesc/HexagonBaseInfo.h    |   2 +-
 2 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index 258e540d6bc0c..a6ec800809f3e 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -4783,6 +4783,120 @@ bool HexagonInstrInfo::isQFPMul(const MachineInstr *MI) const {
           MI->getOpcode() == Hexagon::V6_vmpy_qf32);
 }
 
+namespace llvm::HexagonII {
+
+static constexpr RegTypeInfo make(RegType Out, RegType In1 = RegType::Unknown,
+                                  RegType In2 = RegType::Unknown,
+                                  RegType In3 = RegType::Unknown) {
+  RegTypeInfo I;
+  I.Output = Out;
+  I.Input1 = In1;
+  I.Input2 = In2;
+  I.Input3 = In3;
+  return I;
+}
+
+RegTypeInfo getRegTypeInfo(unsigned Opcode) {
+  switch (Opcode) {
+  default:
+    return {};
+
+  // Generated from qf reg-type metadata.
+  case Hexagon::V6_vabs_qf16_hf:
+    return make(RegType::QF16);
+  case Hexagon::V6_vabs_qf16_qf16:
+    return make(RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vabs_qf32_qf32:
+    return make(RegType::QF32, RegType::QF32);
+  case Hexagon::V6_vabs_qf32_sf:
+    return make(RegType::QF32);
+  case Hexagon::V6_vadd_hf:
+    return make(RegType::QF16);
+  case Hexagon::V6_vadd_qf16:
+    return make(RegType::QF16, RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vadd_qf16_mix:
+    return make(RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vadd_qf32:
+    return make(RegType::QF32, RegType::QF32, RegType::QF32);
+  case Hexagon::V6_vadd_qf32_mix:
+    return make(RegType::QF32, RegType::QF32);
+  case Hexagon::V6_vadd_sf:
+    return make(RegType::QF32);
+  case Hexagon::V6_vconv_bf_qf32:
+    return make(RegType::Unknown, RegType::QF32);
+  case Hexagon::V6_vconv_f8_qf16:
+    return make(RegType::Unknown, RegType::QF16);
+  case Hexagon::V6_vconv_hf_qf16:
+    return make(RegType::Unknown, RegType::QF16);
+  case Hexagon::V6_vconv_hf_qf32:
+    return make(RegType::Unknown, RegType::QF32);
+  case Hexagon::V6_vconv_qf16_f8:
+    return make(RegType::QF16);
+  case Hexagon::V6_vconv_qf16_hf:
+    return make(RegType::QF16);
+  case Hexagon::V6_vconv_qf16_qf16:
+    return make(RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vconv_qf32_qf32:
+    return make(RegType::QF32, RegType::QF32);
+  case Hexagon::V6_vconv_qf32_sf:
+    return make(RegType::QF32);
+  case Hexagon::V6_vconv_sf_qf32:
+    return make(RegType::Unknown, RegType::QF32);
+  case Hexagon::V6_vilog2_qf16:
+    return make(RegType::Unknown, RegType::QF16);
+  case Hexagon::V6_vilog2_qf32:
+    return make(RegType::Unknown, RegType::QF32);
+  case Hexagon::V6_vmpy_qf16:
+    return make(RegType::QF16, RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vmpy_qf16_hf:
+    return make(RegType::QF16);
+  case Hexagon::V6_vmpy_qf16_mix_hf:
+    return make(RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vmpy_qf32:
+    return make(RegType::QF32, RegType::QF32, RegType::QF32);
+  case Hexagon::V6_vmpy_qf32_hf:
+    return make(RegType::QF32);
+  case Hexagon::V6_vmpy_qf32_mix_hf:
+    return make(RegType::QF32, RegType::QF16);
+  case Hexagon::V6_vmpy_qf32_qf16:
+    return make(RegType::QF32, RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vmpy_qf32_sf:
+    return make(RegType::QF32);
+  case Hexagon::V6_vmpy_rt_hf:
+    return make(RegType::QF16);
+  case Hexagon::V6_vmpy_rt_qf16:
+    return make(RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vmpy_rt_sf:
+    return make(RegType::QF32);
+  case Hexagon::V6_vneg_qf16_hf:
+    return make(RegType::QF16);
+  case Hexagon::V6_vneg_qf16_qf16:
+    return make(RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vneg_qf32_qf32:
+    return make(RegType::QF32, RegType::QF32);
+  case Hexagon::V6_vneg_qf32_sf:
+    return make(RegType::QF32);
+  case Hexagon::V6_vsub_hf:
+    return make(RegType::QF16);
+  case Hexagon::V6_vsub_qf16:
+    return make(RegType::QF16, RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vsub_qf16_mix:
+    return make(RegType::QF16, RegType::QF16);
+  case Hexagon::V6_vsub_qf32:
+    return make(RegType::QF32, RegType::QF32, RegType::QF32);
+  case Hexagon::V6_vsub_qf32_mix:
+    return make(RegType::QF32, RegType::QF32);
+  case Hexagon::V6_vsub_sf:
+    return make(RegType::QF32);
+  case Hexagon::V6_vsub_sf_mix:
+    return make(RegType::QF32, RegType::Unknown, RegType::QF32);
+  case Hexagon::V6_vsub_hf_mix:
+    return make(RegType::QF16, RegType::Unknown, RegType::QF16);
+  }
+}
+
+} // namespace llvm::HexagonII
+
 bool HexagonInstrInfo::usesQF32Operand(MachineInstr *MI, unsigned Index) const {
   auto Info = HexagonII::getRegTypeInfo(MI->getOpcode());
   switch (Index) {
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
index 995b7bb1f245e..3c5cf4b069ce3 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
@@ -63,7 +63,7 @@ namespace HexagonII {
     RegType Input3 = RegType::Unknown;
   };
 
-  inline RegTypeInfo getRegTypeInfo(unsigned /*Opcode*/) { return {}; }
+  RegTypeInfo getRegTypeInfo(unsigned Opcode);
 
   inline RegType getOpRegType(unsigned Opcode) {
     return getRegTypeInfo(Opcode).Output;



More information about the llvm-commits mailing list