Skip to content

Commit 53efbc1

Browse files
author
Simon Moll
committed
[VE] v256i1 broadcast isel and tests
Reviewed By: kaz7 Differential Revision: https://reviews.llvm.org/D119241
1 parent ef378d7 commit 53efbc1

File tree

6 files changed

+156
-7
lines changed

6 files changed

+156
-7
lines changed

llvm/lib/Target/VE/VE.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,5 +370,8 @@ inline static uint64_t mimm2Val(uint64_t Val) {
370370
inline unsigned M0(unsigned Val) { return Val + 64; }
371371
inline unsigned M1(unsigned Val) { return Val; }
372372

373+
static const unsigned StandardVectorWidth = 256;
374+
static const unsigned PackedVectorWidth = 512;
375+
373376
} // namespace llvm
374377
#endif

llvm/lib/Target/VE/VECustomDAG.cpp

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,28 @@
1919

2020
namespace llvm {
2121

22-
static const int StandardVectorWidth = 256;
23-
2422
bool isPackedVectorType(EVT SomeVT) {
2523
if (!SomeVT.isVector())
2624
return false;
2725
return SomeVT.getVectorNumElements() > StandardVectorWidth;
2826
}
2927

28+
MVT getLegalVectorType(Packing P, MVT ElemVT) {
29+
return MVT::getVectorVT(ElemVT, P == Packing::Normal ? StandardVectorWidth
30+
: PackedVectorWidth);
31+
}
32+
33+
Packing getTypePacking(EVT VT) {
34+
assert(VT.isVector());
35+
return isPackedVectorType(VT) ? Packing::Dense : Packing::Normal;
36+
}
37+
38+
bool isMaskType(EVT SomeVT) {
39+
if (!SomeVT.isVector())
40+
return false;
41+
return SomeVT.getVectorElementType() == MVT::i1;
42+
}
43+
3044
/// \returns the VVP_* SDNode opcode corresponsing to \p OC.
3145
Optional<unsigned> getVVPOpcode(unsigned Opcode) {
3246
switch (Opcode) {
@@ -121,11 +135,55 @@ SDValue VECustomDAG::getConstant(uint64_t Val, EVT VT, bool IsTarget,
121135
return DAG.getConstant(Val, DL, VT, IsTarget, IsOpaque);
122136
}
123137

138+
SDValue VECustomDAG::getConstantMask(Packing Packing, bool AllTrue) const {
139+
auto MaskVT = getLegalVectorType(Packing, MVT::i1);
140+
141+
// VEISelDAGtoDAG will replace this pattern with the constant-true VM.
142+
auto TrueVal = DAG.getConstant(-1, DL, MVT::i32);
143+
auto AVL = getConstant(MaskVT.getVectorNumElements(), MVT::i32);
144+
auto Res = getNode(VEISD::VEC_BROADCAST, MaskVT, {TrueVal, AVL});
145+
if (AllTrue)
146+
return Res;
147+
148+
return DAG.getNOT(DL, Res, Res.getValueType());
149+
}
150+
151+
SDValue VECustomDAG::getMaskBroadcast(EVT ResultVT, SDValue Scalar,
152+
SDValue AVL) const {
153+
// Constant mask splat.
154+
if (auto BcConst = dyn_cast<ConstantSDNode>(Scalar))
155+
return getConstantMask(getTypePacking(ResultVT),
156+
BcConst->getSExtValue() != 0);
157+
158+
// Expand the broadcast to a vector comparison.
159+
auto ScalarBoolVT = Scalar.getSimpleValueType();
160+
assert(ScalarBoolVT == MVT::i32);
161+
162+
// Cast to i32 ty.
163+
SDValue CmpElem = DAG.getSExtOrTrunc(Scalar, DL, MVT::i32);
164+
unsigned ElemCount = ResultVT.getVectorNumElements();
165+
MVT CmpVecTy = MVT::getVectorVT(ScalarBoolVT, ElemCount);
166+
167+
// Broadcast to vector.
168+
SDValue BCVec =
169+
DAG.getNode(VEISD::VEC_BROADCAST, DL, CmpVecTy, {CmpElem, AVL});
170+
SDValue ZeroVec =
171+
getBroadcast(CmpVecTy, {DAG.getConstant(0, DL, ScalarBoolVT)}, AVL);
172+
173+
MVT BoolVecTy = MVT::getVectorVT(MVT::i1, ElemCount);
174+
175+
// Broadcast(Data) != Broadcast(0)
176+
// TODO: Use a VVP operation for this.
177+
return DAG.getSetCC(DL, BoolVecTy, BCVec, ZeroVec, ISD::CondCode::SETNE);
178+
}
179+
124180
SDValue VECustomDAG::getBroadcast(EVT ResultVT, SDValue Scalar,
125181
SDValue AVL) const {
126182
assert(ResultVT.isVector());
127183
auto ScaVT = Scalar.getValueType();
128-
assert(ScaVT != MVT::i1 && "TODO: Mask broadcasts");
184+
185+
if (isMaskType(ResultVT))
186+
return getMaskBroadcast(ResultVT, Scalar, AVL);
129187

130188
if (isPackedVectorType(ResultVT)) {
131189
// v512x packed mode broadcast

llvm/lib/Target/VE/VECustomDAG.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ bool isVVPBinaryOp(unsigned Opcode);
2727

2828
bool isPackedVectorType(EVT SomeVT);
2929

30+
bool isMaskType(EVT SomeVT);
31+
3032
bool isVVPOrVEC(unsigned);
3133

3234
bool maySafelyIgnoreMask(SDValue Op);
@@ -73,6 +75,17 @@ std::pair<SDValue, bool> getAnnotatedNodeAVL(SDValue);
7375

7476
/// } AVL Functions
7577

78+
enum class Packing {
79+
Normal = 0, // 256 element standard mode.
80+
Dense = 1 // 512 element packed mode.
81+
};
82+
83+
// Get the vector or mask register type for this packing and element type.
84+
MVT getLegalVectorType(Packing P, MVT ElemVT);
85+
86+
// Whether this type belongs to a packed mask or vector register.
87+
Packing getTypePacking(EVT);
88+
7689
class VECustomDAG {
7790
SelectionDAG &DAG;
7891
SDLoc DL;
@@ -117,6 +130,8 @@ class VECustomDAG {
117130
SDValue getConstant(uint64_t Val, EVT VT, bool IsTarget = false,
118131
bool IsOpaque = false) const;
119132

133+
SDValue getConstantMask(Packing Packing, bool AllTrue) const;
134+
SDValue getMaskBroadcast(EVT ResultVT, SDValue Scalar, SDValue AVL) const;
120135
SDValue getBroadcast(EVT ResultVT, SDValue Scalar, SDValue AVL) const;
121136

122137
// Wrap AVL in a LEGALAVL node (unless it is one already).

llvm/lib/Target/VE/VEISelDAGToDAG.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "VE.h"
1314
#include "VETargetMachine.h"
1415
#include "llvm/CodeGen/MachineRegisterInfo.h"
1516
#include "llvm/CodeGen/SelectionDAGISel.h"
@@ -341,6 +342,36 @@ void VEDAGToDAGISel::Select(SDNode *N) {
341342
ReplaceNode(N, N->getOperand(0).getNode());
342343
return;
343344

345+
// Lower (broadcast 1) and (broadcast 0) to VM[P]0
346+
case VEISD::VEC_BROADCAST: {
347+
MVT SplatResTy = N->getSimpleValueType(0);
348+
if (SplatResTy.getVectorElementType() != MVT::i1)
349+
break;
350+
351+
// Constant non-zero broadcast.
352+
auto BConst = dyn_cast<ConstantSDNode>(N->getOperand(0));
353+
if (!BConst)
354+
break;
355+
bool BCTrueMask = (BConst->getSExtValue() != 0);
356+
if (!BCTrueMask)
357+
break;
358+
359+
// Packed or non-packed.
360+
SDValue New;
361+
if (SplatResTy.getVectorNumElements() == StandardVectorWidth) {
362+
New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VM0,
363+
MVT::v256i1);
364+
} else if (SplatResTy.getVectorNumElements() == PackedVectorWidth) {
365+
New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VMP0,
366+
MVT::v512i1);
367+
} else
368+
break;
369+
370+
// Replace.
371+
ReplaceNode(N, New.getNode());
372+
return;
373+
}
374+
344375
case VEISD::GLOBAL_BASE_REG:
345376
ReplaceNode(N, getGlobalBaseReg());
346377
return;

llvm/lib/Target/VE/VEISelLowering.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ bool VETargetLowering::CanLowerReturn(
7676
static const MVT AllVectorVTs[] = {MVT::v256i32, MVT::v512i32, MVT::v256i64,
7777
MVT::v256f32, MVT::v512f32, MVT::v256f64};
7878

79+
static const MVT AllMaskVTs[] = {MVT::v256i1, MVT::v512i1};
80+
7981
static const MVT AllPackedVTs[] = {MVT::v512i32, MVT::v512f32};
8082

8183
void VETargetLowering::initRegisterClasses() {
@@ -294,6 +296,9 @@ void VETargetLowering::initSPUActions() {
294296
}
295297

296298
void VETargetLowering::initVPUActions() {
299+
for (MVT LegalMaskVT : AllMaskVTs)
300+
setOperationAction(ISD::BUILD_VECTOR, LegalMaskVT, Custom);
301+
297302
for (MVT LegalVecVT : AllVectorVTs) {
298303
setOperationAction(ISD::BUILD_VECTOR, LegalVecVT, Custom);
299304
setOperationAction(ISD::INSERT_VECTOR_ELT, LegalVecVT, Legal);
@@ -1661,7 +1666,7 @@ SDValue VETargetLowering::lowerBUILD_VECTOR(SDValue Op,
16611666
if (SDValue ScalarV = getSplatValue(Op.getNode())) {
16621667
unsigned NumEls = ResultVT.getVectorNumElements();
16631668
auto AVL = CDAG.getConstant(NumEls, MVT::i32);
1664-
return CDAG.getBroadcast(ResultVT, Op.getOperand(0), AVL);
1669+
return CDAG.getBroadcast(ResultVT, ScalarV, AVL);
16651670
}
16661671

16671672
// Expand
@@ -2696,9 +2701,9 @@ SDValue VETargetLowering::lowerToVVP(SDValue Op, SelectionDAG &DAG) const {
26962701

26972702
// The representative and legalized vector type of this operation.
26982703
VECustomDAG CDAG(DAG, Op);
2699-
MVT MaskVT = MVT::v256i1; // TODO: packed mode.
27002704
EVT OpVecVT = Op.getValueType();
27012705
EVT LegalVecVT = getTypeToTransformTo(*DAG.getContext(), OpVecVT);
2706+
auto Packing = getTypePacking(LegalVecVT.getSimpleVT());
27022707

27032708
SDValue AVL;
27042709
SDValue Mask;
@@ -2713,8 +2718,7 @@ SDValue VETargetLowering::lowerToVVP(SDValue Op, SelectionDAG &DAG) const {
27132718
} else {
27142719
// Materialize the VL parameter.
27152720
AVL = CDAG.getConstant(OpVecVT.getVectorNumElements(), MVT::i32);
2716-
SDValue ConstTrue = CDAG.getConstant(1, MVT::i32);
2717-
Mask = CDAG.getBroadcast(MaskVT, ConstTrue, AVL);
2721+
Mask = CDAG.getConstantMask(Packing, true);
27182722
}
27192723

27202724
if (isVVPBinaryOp(VVPOpcode)) {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=ve-unknown-unknown -mattr=+vpu | FileCheck %s
3+
4+
define fastcc <256 x i1> @brd_v256i1_s(i1 %s) {
5+
; CHECK-LABEL: brd_v256i1_s:
6+
; CHECK: # %bb.0:
7+
; CHECK-NEXT: and %s0, %s0, (32)0
8+
; CHECK-NEXT: lea %s1, 256
9+
; CHECK-NEXT: lvl %s1
10+
; CHECK-NEXT: vbrd %v0, %s0
11+
; CHECK-NEXT: vbrd %v1, 0
12+
; CHECK-NEXT: vcmpu.w %v0, %v0, %v1
13+
; CHECK-NEXT: vfmk.w.ne %vm1, %v0
14+
; CHECK-NEXT: b.l.t (, %s10)
15+
%val = insertelement <256 x i1> undef, i1 %s, i32 0
16+
%ret = shufflevector <256 x i1> %val, <256 x i1> undef, <256 x i32> zeroinitializer
17+
ret <256 x i1> %ret
18+
}
19+
20+
define fastcc <256 x i1> @brd_v256i1_zero() {
21+
; CHECK-LABEL: brd_v256i1_zero:
22+
; CHECK: # %bb.0:
23+
; CHECK-NEXT: xorm %vm1, %vm0, %vm0
24+
; CHECK-NEXT: b.l.t (, %s10)
25+
%val = insertelement <256 x i1> undef, i1 0, i32 0
26+
%ret = shufflevector <256 x i1> %val, <256 x i1> undef, <256 x i32> zeroinitializer
27+
ret <256 x i1> %ret
28+
}
29+
30+
define fastcc <256 x i1> @brd_v256i1_one() {
31+
; CHECK-LABEL: brd_v256i1_one:
32+
; CHECK: # %bb.0:
33+
; CHECK-NEXT: andm %vm1, %vm0, %vm0
34+
; CHECK-NEXT: b.l.t (, %s10)
35+
%val = insertelement <256 x i1> undef, i1 1, i32 0
36+
%ret = shufflevector <256 x i1> %val, <256 x i1> undef, <256 x i32> zeroinitializer
37+
ret <256 x i1> %ret
38+
}

0 commit comments

Comments
 (0)