Skip to content

Commit 04b6ea6

Browse files
quic-santdaspkarveti
authored andcommitted
[Hexagon] Add pattern for hvx uint_to_fp lowering
The pattern for this particular lowering does not handle conversion from v32i32 to v32f32. This pattern is added which maintains precision during conversion. patch-by: Santanu Das Change-Id: I5022fd237f8db61f4c087647e41089d1bb6c4aaf
1 parent 0864965 commit 04b6ea6

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,8 @@ void HexagonDAGToDAGISel::Select(SDNode *N) {
10241024
case ISD::VECTOR_SHUFFLE: return SelectHvxShuffle(N);
10251025

10261026
case HexagonISD::VROR: return SelectHvxRor(N);
1027+
case ISD::UINT_TO_FP:
1028+
return SelectHvxUIntToFp(N);
10271029
}
10281030
}
10291031

llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class HexagonDAGToDAGISel : public SelectionDAGISel {
146146
void SelectHvxShuffle(SDNode *N);
147147
void SelectHvxRor(SDNode *N);
148148
void SelectHvxVAlign(SDNode *N);
149+
void SelectHvxUIntToFp(SDNode *N);
149150

150151
// Function postprocessing.
151152
void updateAligna();

llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,7 @@ namespace llvm {
947947
void selectShuffle(SDNode *N);
948948
void selectRor(SDNode *N);
949949
void selectVAlign(SDNode *N);
950+
void selectUintToFp(SDNode *N);
950951

951952
static SmallVector<uint32_t, 8> getPerfectCompletions(ShuffleMask SM,
952953
unsigned Width);
@@ -1149,6 +1150,36 @@ bool HvxSelector::selectVectorConstants(SDNode *N) {
11491150
return !Nodes.empty();
11501151
}
11511152

1153+
// UNIT_TO_FP handler for vector type v32i32 --> v32f32
1154+
// V1 = 0
1155+
// V2.uw=vavg(V0.uw, V1.uw) ---> V2 = V0 >> 1
1156+
// V3.w = vsub(V0.w, V2.w) ----> V3 = V0 - V2
1157+
// V4.sf=(V2).w ----> convert V2 to float V4
1158+
// V5.sf=(V3).w ----> convert V3 to float V5
1159+
// V6.sf=vadd(V4.sf, V5.sf) ----> vadd(V4, V5)
1160+
void HvxSelector::selectUintToFp(SDNode *N) {
1161+
1162+
if (!(N->getValueType(0) == MVT::v32f32) ||
1163+
!(N->getOperand(0).getValueType() == MVT::v32i32)) {
1164+
ISel.SelectCode(N);
1165+
return;
1166+
}
1167+
1168+
const SDLoc &dl(N);
1169+
SDNode *ConstZero = DAG.getMachineNode(Hexagon::V6_vd0, dl, MVT::v32i32);
1170+
SDNode *Vavg = DAG.getMachineNode(Hexagon::V6_vavguw, dl, MVT::v32i32,
1171+
N->getOperand(0), SDValue(ConstZero, 0));
1172+
SDNode *Vsubw = DAG.getMachineNode(Hexagon::V6_vsubw, dl, MVT::v32i32,
1173+
N->getOperand(0), SDValue(Vavg, 0));
1174+
SDNode *FirstConv = DAG.getMachineNode(Hexagon::V6_vconv_sf_w, dl,
1175+
MVT::v32f32, SDValue(Vavg, 0));
1176+
SDNode *SecConv = DAG.getMachineNode(Hexagon::V6_vconv_sf_w, dl, MVT::v32f32,
1177+
SDValue(Vsubw, 0));
1178+
SDNode *Vadd = DAG.getMachineNode(Hexagon::V6_vadd_sf_sf, dl, MVT::v32f32,
1179+
SDValue(FirstConv, 0), SDValue(SecConv, 0));
1180+
ISel.ReplaceNode(N, Vadd);
1181+
}
1182+
11521183
void HvxSelector::materialize(const ResultStack &Results) {
11531184
DEBUG_WITH_TYPE("isel", {
11541185
dbgs() << "Materializing\n";
@@ -2874,6 +2905,10 @@ void HexagonDAGToDAGISel::SelectHvxVAlign(SDNode *N) {
28742905
HvxSelector(*this, *CurDAG).selectVAlign(N);
28752906
}
28762907

2908+
void HexagonDAGToDAGISel::SelectHvxUIntToFp(SDNode *N) {
2909+
HvxSelector(*this, *CurDAG).selectUintToFp(N);
2910+
}
2911+
28772912
void HexagonDAGToDAGISel::SelectV65GatherPred(SDNode *N) {
28782913
const SDLoc &dl(N);
28792914
SDValue Chain = N->getOperand(0);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; Check if int_to_fp is lowered correctly for v32i32 --> v32f32
2+
3+
; RUN: llc -march=hexagon -stop-after=hexagon-isel -o - %s | FileCheck %s
4+
5+
; CHECK: [[R2:%[0-9]+]]:hvxvr = V6_vd0
6+
; CHECK-NEXT: [[R3:%[0-9]+]]:hvxvr = V6_vavguw %0, [[R2]]
7+
; CHECK-NEXT: [[R4:%[0-9]+]]:hvxvr = V6_vconv_sf_w [[R3]]
8+
; CHECK-NEXT: [[R5:%[0-9]+]]:hvxvr = V6_vsubw %0, [[R3]]
9+
; CHECK-NEXT: [[R6:%[0-9]+]]:hvxvr = V6_vconv_sf_w killed [[R5]]
10+
; CHECK-NEXT: [[R7:%[0-9]+]]:hvxvr = V6_vadd_sf_sf killed [[R4]], killed [[R6]]
11+
; CHECK-NEXT: [[R8:%[0-9]+]]:hvxvr = V6_vavguw %1, [[R2]]
12+
; CHECK-NEXT: [[R9:%[0-9]+]]:hvxvr = V6_vconv_sf_w [[R8]]
13+
; CHECK-NEXT: [[R10:%[0-9]+]]:hvxvr = V6_vsubw %1, [[R8]]
14+
; CHECK-NEXT: [[R11:%[0-9]+]]:hvxvr = V6_vconv_sf_w killed [[R10]]
15+
; CHECK-NEXT: [[R12:%[0-9]+]]:hvxvr = V6_vadd_sf_sf killed [[R9]], killed [[R11]]
16+
; CHECK-NEXT: V6_vmpy_qf32_sf killed [[R7]], killed [[R12]]
17+
18+
19+
target triple = "hexagon"
20+
define <32 x float> @uitofp(<32 x i32> %int0, <32 x i32> %int1) #0
21+
{
22+
%fp0 = uitofp <32 x i32> %int0 to <32 x float>
23+
%fp1 = uitofp <32 x i32> %int1 to <32 x float>
24+
%out = fmul <32 x float> %fp0, %fp1
25+
ret <32 x float> %out
26+
}
27+
attributes #0 = { nounwind readnone "target-cpu"="hexagonv79" "target-features"="+hvxv79,+hvx-length128b" }

0 commit comments

Comments
 (0)