[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