Skip to content

Commit 9155b03

Browse files
author
Simon Moll
committed
[VP] TTI and lowering to non-VP ops
The ExpandVectorPredication pass lowers VP intrinsics into non-VP operations. Also, TTI queries for VP intrinsic support in a target. This patch is part of the integer patch set of the Vector Predication extension (D57504). VP / integer slice / patch #2
1 parent 134829f commit 9155b03

22 files changed

+606
-1
lines changed

llvm/include/llvm/Analysis/TargetTransformInfo.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class BranchInst;
4545
class Function;
4646
class GlobalValue;
4747
class IntrinsicInst;
48+
class PredicatedInstruction;
4849
class LoadInst;
4950
class LoopAccessInfo;
5051
class Loop;
@@ -1148,6 +1149,15 @@ class TargetTransformInfo {
11481149
bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
11491150
ReductionFlags Flags) const;
11501151

1152+
/// \returns True if the vector length parameter should be folded into the
1153+
/// vector mask.
1154+
bool
1155+
shouldFoldVectorLengthIntoMask(const PredicatedInstruction &PredInst) const;
1156+
1157+
/// \returns False if this VP op should be replaced by a non-VP op or an
1158+
/// unpredicated op plus a select.
1159+
bool supportsVPOperation(const PredicatedInstruction &PredInst) const;
1160+
11511161
/// \returns True if the target wants to expand the given reduction intrinsic
11521162
/// into a shuffle sequence.
11531163
bool shouldExpandReduction(const IntrinsicInst *II) const;
@@ -1400,6 +1410,10 @@ class TargetTransformInfo::Concept {
14001410
virtual unsigned getStoreVectorFactor(unsigned VF, unsigned StoreSize,
14011411
unsigned ChainSizeInBytes,
14021412
VectorType *VecTy) const = 0;
1413+
virtual bool shouldFoldVectorLengthIntoMask(
1414+
const PredicatedInstruction &PredInst) const = 0;
1415+
virtual bool
1416+
supportsVPOperation(const PredicatedInstruction &PredInst) const = 0;
14031417
virtual bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
14041418
ReductionFlags) const = 0;
14051419
virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0;
@@ -1879,6 +1893,13 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
18791893
VectorType *VecTy) const override {
18801894
return Impl.getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy);
18811895
}
1896+
bool shouldFoldVectorLengthIntoMask(
1897+
const PredicatedInstruction &PredInst) const override {
1898+
return Impl.shouldFoldVectorLengthIntoMask(PredInst);
1899+
}
1900+
bool supportsVPOperation(const PredicatedInstruction &PredInst) const {
1901+
return Impl.supportsVPOperation(PredInst);
1902+
}
18821903
bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
18831904
ReductionFlags Flags) const override {
18841905
return Impl.useReductionIntrinsic(Opcode, Ty, Flags);

llvm/include/llvm/Analysis/TargetTransformInfoImpl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,15 @@ class TargetTransformInfoImplBase {
607607
return VF;
608608
}
609609

610+
bool
611+
shouldFoldVectorLengthIntoMask(const PredicatedInstruction &PredInst) const {
612+
return true;
613+
}
614+
615+
bool supportsVPOperation(const PredicatedInstruction &PredInst) const {
616+
return false;
617+
}
618+
610619
bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
611620
TTI::ReductionFlags Flags) const {
612621
return false;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===----- ExpandVectorPredication.h - Expand vector predication --===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CODEGEN_EXPANDVECTORPREDICATION_H
10+
#define LLVM_CODEGEN_EXPANDVECTORPREDICATION_H
11+
12+
#include "llvm/IR/PassManager.h"
13+
14+
namespace llvm {
15+
16+
class ExpandVectorPredicationPass
17+
: public PassInfoMixin<ExpandVectorPredicationPass> {
18+
public:
19+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
20+
};
21+
} // end namespace llvm
22+
23+
#endif // LLVM_CODEGEN_EXPANDVECTORPREDICATION_H

llvm/include/llvm/CodeGen/Passes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,11 @@ namespace llvm {
444444
/// shuffles.
445445
FunctionPass *createExpandReductionsPass();
446446

447+
/// This pass expands the vector predication intrinsics into unpredicated
448+
/// instructions with selects or just the explicit vector length into the
449+
/// predicate mask.
450+
FunctionPass *createExpandVectorPredicationPass();
451+
447452
// This pass expands memcmp() to load/stores.
448453
FunctionPass *createExpandMemCmpPass();
449454

llvm/include/llvm/IR/IntrinsicInst.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,15 @@ namespace llvm {
218218
// Whether \p ID is a VP intrinsic ID.
219219
static bool IsVPIntrinsic(Intrinsic::ID);
220220

221+
/// set the mask parameter.
222+
/// this asserts if the underlying intrinsic has no mask parameter.
223+
void setMaskParam(Value *);
224+
225+
/// set the vector length parameter.
226+
/// this asserts if the underlying intrinsic has no vector length
227+
/// parameter.
228+
void setVectorLengthParam(Value *);
229+
221230
/// \return the mask parameter or nullptr.
222231
Value *getMaskParam() const;
223232

@@ -231,6 +240,9 @@ namespace llvm {
231240
/// length parameter applies to.
232241
ElementCount getVectorLength() const;
233242

243+
bool isBinaryOp() const;
244+
static bool IsBinaryVPOp(Intrinsic::ID);
245+
234246
// Methods for support type inquiry through isa, cast, and dyn_cast:
235247
static bool classof(const IntrinsicInst *I) {
236248
return IsVPIntrinsic(I->getIntrinsicID());

llvm/include/llvm/IR/PredicatedInst.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//===-- llvm/PredicatedInst.h - Predication utility subclass --*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines various classes for working with predicated instructions.
10+
// Predicated instructions are either regular instructions or calls to
11+
// Vector Predication (VP) intrinsics that have a mask and an explicit
12+
// vector length argument.
13+
//
14+
//===----------------------------------------------------------------------===//
15+
16+
#ifndef LLVM_IR_PREDICATEDINST_H
17+
#define LLVM_IR_PREDICATEDINST_H
18+
19+
#include "llvm/ADT/None.h"
20+
#include "llvm/ADT/Optional.h"
21+
#include "llvm/IR/Constants.h"
22+
#include "llvm/IR/Instruction.h"
23+
#include "llvm/IR/IntrinsicInst.h"
24+
#include "llvm/IR/Operator.h"
25+
#include "llvm/IR/Type.h"
26+
#include "llvm/IR/Value.h"
27+
#include "llvm/Support/Casting.h"
28+
29+
#include <cstddef>
30+
31+
namespace llvm {
32+
33+
class BasicBlock;
34+
35+
class PredicatedInstruction : public User {
36+
public:
37+
// The PredicatedInstruction class is intended to be used as a utility, and is
38+
// never itself instantiated.
39+
PredicatedInstruction() = delete;
40+
~PredicatedInstruction() = delete;
41+
42+
void *operator new(size_t s) = delete;
43+
44+
Value *getMaskParam() const {
45+
auto thisVP = dyn_cast<VPIntrinsic>(this);
46+
if (!thisVP)
47+
return nullptr;
48+
return thisVP->getMaskParam();
49+
}
50+
51+
Value *getVectorLengthParam() const {
52+
auto thisVP = dyn_cast<VPIntrinsic>(this);
53+
if (!thisVP)
54+
return nullptr;
55+
return thisVP->getVectorLengthParam();
56+
}
57+
58+
/// \returns True if the passed vector length value has no predicating effect
59+
/// on the op.
60+
bool canIgnoreVectorLengthParam() const;
61+
62+
/// \return True if the static operator of this instruction has a mask or
63+
/// vector length parameter.
64+
bool isVectorPredicatedOp() const { return isa<VPIntrinsic>(this); }
65+
66+
/// \returns the effective Opcode of this operation (ignoring the mask and
67+
/// vector length param).
68+
unsigned getOpcode() const {
69+
auto *VPInst = dyn_cast<VPIntrinsic>(this);
70+
71+
if (!VPInst) {
72+
return cast<Instruction>(this)->getOpcode();
73+
}
74+
75+
return VPInst->getFunctionalOpcode();
76+
}
77+
78+
static bool classof(const Instruction *I) { return isa<Instruction>(I); }
79+
static bool classof(const ConstantExpr *CE) { return false; }
80+
static bool classof(const Value *V) { return isa<Instruction>(V); }
81+
82+
/// Convenience function for getting all the fast-math flags, which must be an
83+
/// operator which supports these flags. See LangRef.html for the meaning of
84+
/// these flags.
85+
FastMathFlags getFastMathFlags() const;
86+
};
87+
88+
} // namespace llvm
89+
90+
#endif // LLVM_IR_PREDICATEDINST_H

llvm/include/llvm/IR/VPIntrinsics.def

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,59 +26,79 @@
2626
#define HANDLE_VP_TO_OC(VPID, OC)
2727
#endif
2828

29+
// This VP Intrinsic is a binary operator
30+
// (only count data params)
31+
#ifndef HANDLE_VP_IS_BINARY
32+
#define HANDLE_VP_IS_BINARY(VPID)
33+
#endif
34+
2935
///// Integer Arithmetic /////
3036

3137
// llvm.vp.add(x,y,mask,vlen)
3238
REGISTER_VP_INTRINSIC(vp_add, 2, 3)
3339
HANDLE_VP_TO_OC(vp_add, Add)
40+
HANDLE_VP_IS_BINARY(vp_add)
3441

3542
// llvm.vp.and(x,y,mask,vlen)
3643
REGISTER_VP_INTRINSIC(vp_and, 2, 3)
3744
HANDLE_VP_TO_OC(vp_and, And)
45+
HANDLE_VP_IS_BINARY(vp_and)
3846

3947
// llvm.vp.ashr(x,y,mask,vlen)
4048
REGISTER_VP_INTRINSIC(vp_ashr, 2, 3)
4149
HANDLE_VP_TO_OC(vp_ashr, AShr)
50+
HANDLE_VP_IS_BINARY(vp_ashr)
4251

4352
// llvm.vp.lshr(x,y,mask,vlen)
4453
REGISTER_VP_INTRINSIC(vp_lshr, 2, 3)
4554
HANDLE_VP_TO_OC(vp_lshr, LShr)
55+
HANDLE_VP_IS_BINARY(vp_lshr)
4656

4757
// llvm.vp.mul(x,y,mask,vlen)
4858
REGISTER_VP_INTRINSIC(vp_mul, 2, 3)
4959
HANDLE_VP_TO_OC(vp_mul, Mul)
60+
HANDLE_VP_IS_BINARY(vp_mul)
5061

5162
// llvm.vp.or(x,y,mask,vlen)
5263
REGISTER_VP_INTRINSIC(vp_or, 2, 3)
5364
HANDLE_VP_TO_OC(vp_or, Or)
65+
HANDLE_VP_IS_BINARY(vp_or)
5466

5567
// llvm.vp.sdiv(x,y,mask,vlen)
5668
REGISTER_VP_INTRINSIC(vp_sdiv, 2, 3)
5769
HANDLE_VP_TO_OC(vp_sdiv, SDiv)
70+
HANDLE_VP_IS_BINARY(vp_sdiv)
5871

5972
// llvm.vp.shl(x,y,mask,vlen)
6073
REGISTER_VP_INTRINSIC(vp_shl, 2, 3)
6174
HANDLE_VP_TO_OC(vp_shl, Shl)
75+
HANDLE_VP_IS_BINARY(vp_shl)
6276

6377
// llvm.vp.srem(x,y,mask,vlen)
6478
REGISTER_VP_INTRINSIC(vp_srem, 2, 3)
6579
HANDLE_VP_TO_OC(vp_srem, SRem)
80+
HANDLE_VP_IS_BINARY(vp_srem)
6681

6782
// llvm.vp.sub(x,y,mask,vlen)
6883
REGISTER_VP_INTRINSIC(vp_sub, 2, 3)
6984
HANDLE_VP_TO_OC(vp_sub, Sub)
85+
HANDLE_VP_IS_BINARY(vp_sub)
7086

7187
// llvm.vp.udiv(x,y,mask,vlen)
7288
REGISTER_VP_INTRINSIC(vp_udiv, 2, 3)
7389
HANDLE_VP_TO_OC(vp_udiv, UDiv)
90+
HANDLE_VP_IS_BINARY(vp_udiv)
7491

7592
// llvm.vp.urem(x,y,mask,vlen)
7693
REGISTER_VP_INTRINSIC(vp_urem, 2, 3)
7794
HANDLE_VP_TO_OC(vp_urem, URem)
95+
HANDLE_VP_IS_BINARY(vp_urem)
7896

7997
// llvm.vp.xor(x,y,mask,vlen)
8098
REGISTER_VP_INTRINSIC(vp_xor, 2, 3)
8199
HANDLE_VP_TO_OC(vp_xor, Xor)
100+
HANDLE_VP_IS_BINARY(vp_xor)
82101

83102
#undef REGISTER_VP_INTRINSIC
84103
#undef HANDLE_VP_TO_OC
104+
#undef HANDLE_VP_IS_BINARY

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ void initializeEntryExitInstrumenterPass(PassRegistry&);
145145
void initializeExpandMemCmpPassPass(PassRegistry&);
146146
void initializeExpandPostRAPass(PassRegistry&);
147147
void initializeExpandReductionsPass(PassRegistry&);
148+
void initializeExpandVectorPredicationPass(PassRegistry&);
148149
void initializeMakeGuardsExplicitLegacyPassPass(PassRegistry&);
149150
void initializeExternalAAWrapperPassPass(PassRegistry&);
150151
void initializeFEntryInserterPass(PassRegistry&);

llvm/lib/Analysis/TargetTransformInfo.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,16 @@ unsigned TargetTransformInfo::getStoreVectorFactor(unsigned VF,
847847
return TTIImpl->getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy);
848848
}
849849

850+
bool TargetTransformInfo::shouldFoldVectorLengthIntoMask(
851+
const PredicatedInstruction &PI) const {
852+
return TTIImpl->shouldFoldVectorLengthIntoMask(PI);
853+
}
854+
855+
bool TargetTransformInfo::supportsVPOperation(
856+
const PredicatedInstruction &PI) const {
857+
return TTIImpl->supportsVPOperation(PI);
858+
}
859+
850860
bool TargetTransformInfo::useReductionIntrinsic(unsigned Opcode,
851861
Type *Ty, ReductionFlags Flags) const {
852862
return TTIImpl->useReductionIntrinsic(Opcode, Ty, Flags);

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ add_llvm_component_library(LLVMCodeGen
2525
ExpandMemCmp.cpp
2626
ExpandPostRAPseudos.cpp
2727
ExpandReductions.cpp
28+
ExpandVectorPredication.cpp
2829
FaultMaps.cpp
2930
FEntryInserter.cpp
3031
FinalizeISel.cpp

0 commit comments

Comments
 (0)