Skip to content

Commit b22d2a1

Browse files
committed
[Hexagon]Handle bitcast of i32/v2i16/v4i8 -> v32i1 when Hvx is enabled
Change-Id: I1f3c4783424a2c068f207a7680f85ef95c70f573
1 parent 18991f4 commit b22d2a1

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ HexagonTargetLowering::initializeHVXLowering() {
117117
setOperationAction(ISD::VECTOR_SHUFFLE, ByteW, Legal);
118118
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
119119

120+
if (Subtarget.useHVX128BOps())
121+
setOperationAction(ISD::BITCAST, MVT::v32i1, Custom);
120122
if (Subtarget.useHVX128BOps() && Subtarget.useHVXV68Ops() &&
121123
Subtarget.useHVXFloatingPoint()) {
122124

@@ -2001,6 +2003,28 @@ HexagonTargetLowering::LowerHvxBitcast(SDValue Op, SelectionDAG &DAG) const {
20012003

20022004
return DAG.getNode(ISD::BUILD_PAIR, dl, ResTy, Combines);
20032005
}
2006+
2007+
// Handle bitcast from i32, v2i16, and v4i8 to v32i1.
2008+
// Splat the input into a 32-element i32 vector, then AND each element
2009+
// with a unique bitmask to isolate individual bits.
2010+
if (ResTy == MVT::v32i1 &&
2011+
(ValTy == MVT::i32 || ValTy == MVT::v2i16 || ValTy == MVT::v4i8) &&
2012+
Subtarget.useHVX128BOps()) {
2013+
SDValue Val32 = Val;
2014+
if (ValTy == MVT::v2i16 || ValTy == MVT::v4i8)
2015+
Val32 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Val);
2016+
2017+
MVT VecTy = MVT::getVectorVT(MVT::i32, 32);
2018+
SDValue Splat = DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Val32);
2019+
SmallVector<SDValue, 32> Mask;
2020+
for (unsigned i = 0; i < 32; ++i)
2021+
Mask.push_back(DAG.getConstant(1u << i, dl, MVT::i32));
2022+
2023+
SDValue MaskVec = DAG.getBuildVector(VecTy, dl, Mask);
2024+
SDValue Anded = DAG.getNode(ISD::AND, dl, VecTy, Splat, MaskVec);
2025+
return DAG.getNode(HexagonISD::V2Q, dl, ResTy, Anded);
2026+
}
2027+
20042028
if (isHvxBoolTy(ResTy) && ValTy.isScalarInteger()) {
20052029
// Handle bitcast from i128 -> v128i1 and i64 -> v64i1.
20062030
unsigned BitWidth = ValTy.getSizeInBits();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llc --mtriple=hexagon -mattr=+hvxv79,+hvx-length128b < %s | FileCheck %s
2+
3+
; CHECK: [[VREG1:v([0-9]+)]] = vsplat(r{{[0-9]*}})
4+
; CHECK: [[VREG2:v([0-9]+)]] = vand([[VREG1]],v{{[0-9]+}})
5+
; CHECK: q[[QREG:[0-9]+]] = vand([[VREG2]],r{{[0-9]+}})
6+
7+
define void @bitcast_i32_to_v32i1_full(ptr %in, ptr %out) {
8+
entry:
9+
%load = load i32, ptr %in, align 4
10+
%bitcast = bitcast i32 %load to <32 x i1>
11+
%e0 = extractelement <32 x i1> %bitcast, i32 0
12+
%e1 = extractelement <32 x i1> %bitcast, i32 1
13+
%z0 = zext i1 %e0 to i8
14+
%z1 = zext i1 %e1 to i8
15+
%ptr0 = getelementptr i8, ptr %out, i32 0
16+
%ptr1 = getelementptr i8, ptr %out, i32 1
17+
store i8 %z0, ptr %ptr0, align 1
18+
store i8 %z1, ptr %ptr1, align 1
19+
ret void
20+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: llc --mtriple=hexagon -mattr=+hvxv79,+hvx-length128b < %s | FileCheck %s
2+
3+
; CHECK: [[REG0:r[0-9]+]] = memw(r{{[0-9]+}}+#0)
4+
; CHECK: [[VREG1:v([0-9]+)]] = vsplat([[REG0]])
5+
; CHECK: [[VREG2:v([0-9]+)]] = vand([[VREG1]],v{{[0-9]+}})
6+
; CHECK: q[[QREG:[0-9]+]] = vand([[VREG2]],r{{[0-9]+}})
7+
8+
define void @bitcast_v2i16_to_v32i1(ptr %in, ptr %out) {
9+
entry:
10+
%load = load <2 x i16>, ptr %in, align 4
11+
%bitcast = bitcast <2 x i16> %load to <32 x i1>
12+
%extract = extractelement <32 x i1> %bitcast, i32 0
13+
%zext = zext i1 %extract to i8
14+
store i8 %zext, ptr %out, align 1
15+
ret void
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: llc --mtriple=hexagon -mattr=+hvxv79,+hvx-length128b < %s | FileCheck %s
2+
3+
; CHECK: [[REG0:r[0-9]+]] = memw(r{{[0-9]+}}+#0)
4+
; CHECK: [[VREG1:v([0-9]+)]] = vsplat([[REG0]])
5+
; CHECK: [[VREG2:v([0-9]+)]] = vand([[VREG1]],v{{[0-9]+}})
6+
; CHECK: q[[QREG:[0-9]+]] = vand([[VREG2]],r{{[0-9]+}})
7+
8+
define void @bitcast_v4i8_to_v32i1(ptr %in, ptr %out) {
9+
entry:
10+
%load = load <4 x i8>, ptr %in, align 4
11+
%bitcast = bitcast <4 x i8> %load to <32 x i1>
12+
%extract = extractelement <32 x i1> %bitcast, i32 0
13+
%zext = zext i1 %extract to i8
14+
store i8 %zext, ptr %out, align 1
15+
ret void
16+
}

0 commit comments

Comments
 (0)