[llvm] 4ef9275 - [Hexagon] Emit better 32-bit multiplication sequence for HVXv62+
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 13:29:53 PDT 2020
Author: Krzysztof Parzyszek
Date: 2020-08-27T15:24:32-05:00
New Revision: 4ef9275b9b4875a131898ead943e17389e797b12
URL: https://github.com/llvm/llvm-project/commit/4ef9275b9b4875a131898ead943e17389e797b12
DIFF: https://github.com/llvm/llvm-project/commit/4ef9275b9b4875a131898ead943e17389e797b12.diff
LOG: [Hexagon] Emit better 32-bit multiplication sequence for HVXv62+
Added:
Modified:
llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
llvm/test/CodeGen/Hexagon/autohvx/arith.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
index 254e5a89b1aa..ed701728892a 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
@@ -1464,16 +1464,29 @@ HexagonTargetLowering::LowerHvxMul(SDValue Op, SelectionDAG &DAG) const {
// V6_vmpybv.)
return getInstr(Hexagon::V6_vmpyih, dl, ResTy, {Vs, Vt}, DAG);
case MVT::i32: {
- // Use the following sequence for signed word multiply:
- // T0 = V6_vmpyiowh Vs, Vt
- // T1 = V6_vaslw T0, 16
- // T2 = V6_vmpyiewuh_acc T1, Vs, Vt
- SDValue S16 = DAG.getConstant(16, dl, MVT::i32);
- SDValue T0 = getInstr(Hexagon::V6_vmpyiowh, dl, ResTy, {Vs, Vt}, DAG);
- SDValue T1 = getInstr(Hexagon::V6_vaslw, dl, ResTy, {T0, S16}, DAG);
- SDValue T2 = getInstr(Hexagon::V6_vmpyiewuh_acc, dl, ResTy,
- {T1, Vs, Vt}, DAG);
- return T2;
+ auto MulL_V60 = [&](SDValue Vs, SDValue Vt) {
+ // Use the following sequence for signed word multiply:
+ // T0 = V6_vmpyiowh Vs, Vt
+ // T1 = V6_vaslw T0, 16
+ // T2 = V6_vmpyiewuh_acc T1, Vs, Vt
+ SDValue S16 = DAG.getConstant(16, dl, MVT::i32);
+ SDValue T0 = getInstr(Hexagon::V6_vmpyiowh, dl, ResTy, {Vs, Vt}, DAG);
+ SDValue T1 = getInstr(Hexagon::V6_vaslw, dl, ResTy, {T0, S16}, DAG);
+ SDValue T2 = getInstr(Hexagon::V6_vmpyiewuh_acc, dl, ResTy,
+ {T1, Vs, Vt}, DAG);
+ return T2;
+ };
+ auto MulL_V62 = [&](SDValue Vs, SDValue Vt) {
+ MVT PairTy = typeJoin({ResTy, ResTy});
+ SDValue T0 = getInstr(Hexagon::V6_vmpyewuh_64, dl, PairTy,
+ {Vs, Vt}, DAG);
+ SDValue T1 = getInstr(Hexagon::V6_vmpyowh_64_acc, dl, PairTy,
+ {T0, Vs, Vt}, DAG);
+ return opSplit(T1, dl, DAG).first;
+ };
+ if (Subtarget.useHVXV62Ops())
+ return MulL_V62(Vs, Vt);
+ return MulL_V60(Vs, Vt);
}
default:
break;
@@ -1520,7 +1533,7 @@ HexagonTargetLowering::LowerHvxMulh(SDValue Op, SelectionDAG &DAG) const {
assert(ElemTy == MVT::i32);
SDValue S16 = DAG.getConstant(16, dl, MVT::i32);
- if (IsSigned) {
+ auto MulHS_V60 = [&](SDValue Vs, SDValue Vt) {
// mulhs(Vs,Vt) =
// = [(Hi(Vs)*2^16 + Lo(Vs)) *s (Hi(Vt)*2^16 + Lo(Vt))] >> 32
// = [Hi(Vs)*2^16 *s Hi(Vt)*2^16 + Hi(Vs) *su Lo(Vt)*2^16
@@ -1547,6 +1560,20 @@ HexagonTargetLowering::LowerHvxMulh(SDValue Op, SelectionDAG &DAG) const {
// Add:
SDValue T3 = DAG.getNode(ISD::ADD, dl, ResTy, {S2, T2});
return T3;
+ };
+
+ auto MulHS_V62 = [&](SDValue Vs, SDValue Vt) {
+ MVT PairTy = typeJoin({ResTy, ResTy});
+ SDValue T0 = getInstr(Hexagon::V6_vmpyewuh_64, dl, PairTy, {Vs, Vt}, DAG);
+ SDValue T1 = getInstr(Hexagon::V6_vmpyowh_64_acc, dl, PairTy,
+ {T0, Vs, Vt}, DAG);
+ return opSplit(T1, dl, DAG).second;
+ };
+
+ if (IsSigned) {
+ if (Subtarget.useHVXV62Ops())
+ return MulHS_V62(Vs, Vt);
+ return MulHS_V60(Vs, Vt);
}
// Unsigned mulhw. (Would expansion using signed mulhw be better?)
diff --git a/llvm/test/CodeGen/Hexagon/autohvx/arith.ll b/llvm/test/CodeGen/Hexagon/autohvx/arith.ll
index f7b403365c2a..99e287dce214 100644
--- a/llvm/test/CodeGen/Hexagon/autohvx/arith.ll
+++ b/llvm/test/CodeGen/Hexagon/autohvx/arith.ll
@@ -252,25 +252,43 @@ define <64 x i16> @mpyh_128(<64 x i16> %v0, <64 x i16> %v1) #1 {
ret <64 x i16> %p
}
-; CHECK-LABEL: mpyw_64:
+; CHECK-LABEL: mpyw_64_v60:
; CHECK-DAG: r[[T00:[0-9]+]] = #16
; CHECK-DAG: v[[T01:[0-9]+]].w = vmpyio(v0.w,v1.h)
; CHECK: v[[T02:[0-9]+]].w = vasl(v[[T01]].w,r[[T00]])
; CHECK: v[[T02]].w += vmpyie(v0.w,v1.uh)
-define <16 x i32> @mpyw_64(<16 x i32> %v0, <16 x i32> %v1) #0 {
+define <16 x i32> @mpyw_64_v60(<16 x i32> %v0, <16 x i32> %v1) #0 {
%p = mul <16 x i32> %v0, %v1
ret <16 x i32> %p
}
-; CHECK-LABEL: mpyw_128:
+; CHECK-LABEL: mpyw_128_v60:
; CHECK-DAG: r[[T10:[0-9]+]] = #16
; CHECK-DAG: v[[T11:[0-9]+]].w = vmpyio(v0.w,v1.h)
; CHECK: v[[T12:[0-9]+]].w = vasl(v[[T11]].w,r[[T10]])
; CHECK: v[[T12]].w += vmpyie(v0.w,v1.uh)
-define <32 x i32> @mpyw_128(<32 x i32> %v0, <32 x i32> %v1) #1 {
+define <32 x i32> @mpyw_128_v60(<32 x i32> %v0, <32 x i32> %v1) #1 {
+ %p = mul <32 x i32> %v0, %v1
+ ret <32 x i32> %p
+}
+
+; CHECK-LABEL: mpyw_64_v62:
+; CHECK: v[[T00:[0-9]+]]:[[T01:[0-9]+]] = vmpye(v0.w,v1.uh)
+; CHECK: v[[T00]]:[[T01]] += vmpyo(v0.w,v1.h)
+define <16 x i32> @mpyw_64_v62(<16 x i32> %v0, <16 x i32> %v1) #3 {
+ %p = mul <16 x i32> %v0, %v1
+ ret <16 x i32> %p
+}
+
+; CHECK-LABEL: mpyw_128_v62:
+; CHECK: v[[T00:[0-9]+]]:[[T01:[0-9]+]] = vmpye(v0.w,v1.uh)
+; CHECK: v[[T00]]:[[T01]] += vmpyo(v0.w,v1.h)
+define <32 x i32> @mpyw_128_v62(<32 x i32> %v0, <32 x i32> %v1) #4 {
%p = mul <32 x i32> %v0, %v1
ret <32 x i32> %p
}
attributes #0 = { nounwind "target-cpu"="hexagonv60" "target-features"="+hvx,+hvx-length64b" }
attributes #1 = { nounwind "target-cpu"="hexagonv60" "target-features"="+hvx,+hvx-length128b" }
+attributes #3 = { nounwind "target-cpu"="hexagonv62" "target-features"="+hvxv62,+hvx-length64b" }
+attributes #4 = { nounwind "target-cpu"="hexagonv62" "target-features"="+hvxv62,+hvx-length128b" }
More information about the llvm-commits
mailing list