[llvm] [Hexagon] Fix wrong operand in XQFloat qf32 multiply normalization (PR #208489)

Fateme Hosseini via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 9 08:47:04 PDT 2026


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

In convertNormalizeMultOp32, when only the second operand of a V6_vmpy_qf32 comes from an add/sub/mul unit (secondconvert), the generated multiply incorrectly used the raw second operand (Reg2) instead of the first operand (Reg1). This dropped the first operand and multiplied the normalized second operand by the un-normalized second operand.

This patch fixed the multiply to use Reg1 and the normalized input_mpy2, matching the correct arrangement used elsewhere. The bug was not observed on v81 (which takes the V81normalizeMultF32 path); it only affected the v79 fallback.

Co-authored-by: Santanu Das <quic_santdas at qti.qualcomm.com>

>From 3688eaedee38fc43f9a4f8f07fbe91e2debe2c6e Mon Sep 17 00:00:00 2001
From: Fateme Hosseini <fhossein at qti.qualcomm.com>
Date: Wed, 8 Jul 2026 14:14:13 -0700
Subject: [PATCH] [Hexagon] Fix wrong operand in XQFloat qf32 multiply
 normalization

In convertNormalizeMultOp32, when only the second operand of a
V6_vmpy_qf32 comes from an add/sub/mul unit (secondconvert), the
generated multiply incorrectly used the raw second operand (Reg2)
instead of the first operand (Reg1). This dropped the first operand
and multiplied the normalized second operand by the un-normalized
second operand.

Fix the multiply to use Reg1 and the normalized input_mpy2, matching
the correct arrangement used elsewhere. The bug was not observed on
v81 (which takes the V81normalizeMultF32 path); it only affected the
v79 fallback.

Co-authored-by: Santanu Das <quic_santdas at qti.qualcomm.com>
---
 .../Hexagon/HexagonXQFloatGenerator.cpp       |  4 +--
 .../xqf-mult-normalize-second-operand.mir     | 27 +++++++++++++++++++
 2 files changed, 29 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/Hexagon/autohvx/xqf-mult-normalize-second-operand.mir

diff --git a/llvm/lib/Target/Hexagon/HexagonXQFloatGenerator.cpp b/llvm/lib/Target/Hexagon/HexagonXQFloatGenerator.cpp
index a04819aa8f963..68b5d9f9f948d 100644
--- a/llvm/lib/Target/Hexagon/HexagonXQFloatGenerator.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonXQFloatGenerator.cpp
@@ -1394,8 +1394,8 @@ bool HexagonXQFloatGenerator::convertNormalizeMultOp32(
         .addReg(R_mpy)
         .addReg(VR2);
     BuildMI(MBB, MI, DL, HII->get(Hexagon::V6_vmpy_qf32), Dest)
-        .addReg(input_mpy2)
-        .addReg(Reg2);
+        .addReg(Reg1)
+        .addReg(input_mpy2);
   } else {
     // we do nothing if the inputs are not fromadder/subtracter/multiplier unit
     return false;
diff --git a/llvm/test/CodeGen/Hexagon/autohvx/xqf-mult-normalize-second-operand.mir b/llvm/test/CodeGen/Hexagon/autohvx/xqf-mult-normalize-second-operand.mir
new file mode 100644
index 0000000000000..a5d1641fd3662
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/autohvx/xqf-mult-normalize-second-operand.mir
@@ -0,0 +1,27 @@
+# Tests qf32 multiply normalization when only the second operand needs
+# converting: the vmpy must keep the first operand and use the normalized
+# second operand.
+
+# RUN: llc -mtriple=hexagon-unknown-elf -mattr=+hvxv79,+hvx-length128b,+hvx-qfloat \
+# RUN:   -run-pass=hexagon-xqfloat-generator -hexagon-qfloat-mode=strict-ieee \
+# RUN:   -enable-xqf-gen=true %s -o - | FileCheck %s
+
+--- |
+  define void @mul_secondconv() { ret void }
+...
+---
+name:            mul_secondconv
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $v0, $v1, $v2
+    ; CHECK-LABEL: name: mul_secondconv
+    ; CHECK: %4:hvxvr = V6_vmpy_qf32 %1, %{{[0-9]+}}
+    %0:hvxvr = COPY $v0
+    %1:hvxvr = COPY $v1
+    %2:hvxvr = COPY $v2
+    %3:hvxvr = V6_vadd_qf32 %0, %2
+    %4:hvxvr = V6_vmpy_qf32 %1, %3
+    $v0 = COPY %4
+    PS_jmpret $r31, implicit-def dead $pc, implicit $v0
+...



More information about the llvm-commits mailing list