[llvm] 0a984ed - [Hexagon] Optimize sext + mul pattern to use vmpyh instruction (#190316)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 08:17:42 PDT 2026
Author: Chandana Mudda
Date: 2026-04-16T20:47:36+05:30
New Revision: 0a984edbcd2e2f094f45e5ec009d444a947aea18
URL: https://github.com/llvm/llvm-project/commit/0a984edbcd2e2f094f45e5ec009d444a947aea18
DIFF: https://github.com/llvm/llvm-project/commit/0a984edbcd2e2f094f45e5ec009d444a947aea18.diff
LOG: [Hexagon] Optimize sext + mul pattern to use vmpyh instruction (#190316)
This patch adds TableGen patterns to recognize and optimize the pattern:
(v2i32 (mul (sext v2i16), (sext v2i16)))
And transforms it to use the M2_vmpy2s_s0 instruction which generates
the efficient vmpyh (vector multiply halfwords) instruction.
The transform is guarded by `nsw` because `M2_vmpy2s_s0` performs a
saturating signed multiply (`vmpyh(...):sat`), so the replacement is
only semantics-preserving when signed overflow is undefined in the IR.
Currently, this pattern expands to:
r3:2 = vsxthw(r0) // Sign extend
r1:0 = vsxthw(r1) // Sign extend
r1 = mpyi(r3,r1) // Scalar multiply
r0 = mpyi(r2,r0) // Scalar multiply
With this patch, it generates:
r1:0 = vmpyh(r0,r1):sat // Single vector multiply
Co-authored-by: Santanu Das <quic_santdas at quicinc.com>
Added:
llvm/test/CodeGen/Hexagon/sext-mul-v2i16.ll
Modified:
llvm/lib/Target/Hexagon/HexagonPatterns.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index 0c9650585b613..bd79ae2c1a1a8 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -1747,10 +1747,18 @@ def n8_0ImmPred: PatLeaf<(i32 imm), [{
return -255 <= V && V <= 0;
}]>;
+def mulnsw : PatFrag<(ops node:$lhs, node:$rhs),
+ (mul node:$lhs, node:$rhs), [{
+ return N->getFlags().hasNoSignedWrap();
+}]>;
+
// Change the sign of the immediate for Rd=-mpyi(Rs,#u8)
def: Pat<(mul I32:$Rs, n8_0ImmPred:$n8),
(M2_mpysin I32:$Rs, (NegImm8 imm:$n8))>;
+def: Pat<(v2i32 (mulnsw (sext V2I16:$Rs), (sext V2I16:$Rt))),
+ (M2_vmpy2s_s0 V2I16:$Rs, V2I16:$Rt)>;
+
def: Pat<(add Sext64:$Rs, I64:$Rt),
(A2_addsp (LoReg Sext64:$Rs), I64:$Rt)>;
diff --git a/llvm/test/CodeGen/Hexagon/sext-mul-v2i16.ll b/llvm/test/CodeGen/Hexagon/sext-mul-v2i16.ll
new file mode 100644
index 0000000000000..a34a5faa9cc3b
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/sext-mul-v2i16.ll
@@ -0,0 +1,16 @@
+; RUN: llc -O2 -mtriple=hexagon < %s | FileCheck %s
+
+; Test that we optimize sext + mul pattern to use vmpyh instruction
+; instead of expanding to scalar multiplies.
+
+; CHECK-LABEL: test_sext_mul_v2i16:
+; CHECK: vmpyh
+; CHECK-NOT: vsxthw
+; CHECK-NOT: mpyi
+define <2 x i32> @test_sext_mul_v2i16(<2 x i16> %a, <2 x i16> %b) {
+entry:
+ %ext_a = sext <2 x i16> %a to <2 x i32>
+ %ext_b = sext <2 x i16> %b to <2 x i32>
+ %mul = mul nsw <2 x i32> %ext_a, %ext_b
+ ret <2 x i32> %mul
+}
More information about the llvm-commits
mailing list