summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h10
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h71
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp21
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp54
-rw-r--r--llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp35
-rw-r--r--llvm/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp64
6 files changed, 171 insertions, 84 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h
index 7252fedac9e..9252dd94f0d 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h
@@ -60,20 +60,22 @@ public:
/// Legalize an instruction by reducing the width of the underlying scalar
/// type.
- LegalizeResult narrowScalar(MachineInstr &MI, LLT NarrowTy);
+ LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
/// Legalize an instruction by performing the operation on a wider scalar type
/// (for example a 16-bit addition can be safely performed at 32-bits
/// precision, ignoring the unused bits).
- LegalizeResult widenScalar(MachineInstr &MI, LLT WideTy);
+ LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
/// Legalize a vector instruction by splitting into multiple components, each
/// acting on the same scalar type as the original but with fewer elements.
- LegalizeResult fewerElementsVector(MachineInstr &MI, LLT NarrowTy);
+ LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy);
/// Legalize a vector instruction by increasing the number of vector elements
/// involved and ignoring the added elements later.
- LegalizeResult moreElementsVector(MachineInstr &MI, LLT WideTy);
+ LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
+ LLT WideTy);
private:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
index 29398e87207..439f2aeae40 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
@@ -27,6 +27,38 @@ class MachineInstr;
class Type;
class VectorType;
+/// Legalization is decided based on an instruction's opcode, which type slot
+/// we're considering, and what the existing type is. These aspects are gathered
+/// together for convenience in the InstrAspect class.
+struct InstrAspect {
+ unsigned Opcode;
+ unsigned Idx;
+ LLT Type;
+
+ InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Idx(0), Type(Type) {}
+ InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
+ : Opcode(Opcode), Idx(Idx), Type(Type) {}
+
+ bool operator==(const InstrAspect &RHS) const {
+ return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type;
+ }
+};
+
+template <> struct DenseMapInfo<InstrAspect> {
+ static inline InstrAspect getEmptyKey() { return {-1u, 0, LLT{}}; }
+
+ static inline InstrAspect getTombstoneKey() { return {-2u, 0, LLT{}}; }
+
+ static unsigned getHashValue(const InstrAspect &Val) {
+ return DenseMapInfo<std::pair<uint64_t, LLT>>::getHashValue(
+ {(uint64_t)Val.Opcode << 32 | Val.Idx, Val.Type});
+ }
+
+ static bool isEqual(const InstrAspect &LHS, const InstrAspect &RHS) {
+ return LHS == RHS;
+ }
+};
+
class MachineLegalizer {
public:
enum LegalizeAction : std::uint8_t {
@@ -78,9 +110,9 @@ public:
/// More friendly way to set an action for common types that have an LLT
/// representation.
- void setAction(unsigned Opcode, LLT Ty, LegalizeAction Action) {
+ void setAction(const InstrAspect &Aspect, LegalizeAction Action) {
TablesInitialized = false;
- Actions[std::make_pair(Opcode, Ty)] = Action;
+ Actions[Aspect] = Action;
}
/// If an operation on a given vector type (say <M x iN>) isn't explicitly
@@ -96,23 +128,32 @@ public:
/// Determine what action should be taken to legalize the given generic
- /// instruction and type. Requires computeTables to have been called.
+ /// instruction opcode, type-index and type. Requires computeTables to have
+ /// been called.
///
/// \returns a pair consisting of the kind of legalization that should be
/// performed and the destination type.
- std::pair<LegalizeAction, LLT> getAction(unsigned Opcode, LLT) const;
- std::pair<LegalizeAction, LLT> getAction(const MachineInstr &MI) const;
+ std::pair<LegalizeAction, LLT> getAction(const InstrAspect &Aspect) const;
+
+ /// Determine what action should be taken to legalize the given generic instruction.
+ ///
+ /// \returns a tuple consisting of the LegalizeAction that should be
+ /// performed, the type-index it should be performed on and the destination
+ /// type.
+ std::tuple<LegalizeAction, unsigned, LLT>
+ getAction(const MachineInstr &MI) const;
/// Iterate the given function (typically something like doubling the width)
/// on Ty until we find a legal type for this operation.
- LLT findLegalType(unsigned Opcode, LLT Ty,
- std::function<LLT(LLT)> NextType) const {
+ LLT findLegalType(const InstrAspect &Aspect,
+ std::function<LLT(LLT)> NextType) const {
LegalizeAction Action;
+ LLT Ty = Aspect.Type;
do {
Ty = NextType(Ty);
- auto ActionIt = Actions.find(std::make_pair(Opcode, Ty));
+ auto ActionIt = Actions.find({Aspect.Opcode, Aspect.Idx, Ty});
if (ActionIt == Actions.end())
- Action = DefaultActions.find(Opcode)->second;
+ Action = DefaultActions.find(Aspect.Opcode)->second;
else
Action = ActionIt->second;
} while(Action != Legal);
@@ -121,26 +162,28 @@ public:
/// Find what type it's actually OK to perform the given operation on, given
/// the general approach we've decided to take.
- LLT findLegalType(unsigned Opcode, LLT Ty, LegalizeAction Action) const;
+ LLT findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const;
- std::pair<LegalizeAction, LLT> findLegalAction(unsigned Opcode, LLT Ty,
+ std::pair<LegalizeAction, LLT> findLegalAction(const InstrAspect &Aspect,
LegalizeAction Action) const {
- return std::make_pair(Action, findLegalType(Opcode, Ty, Action));
+ return std::make_pair(Action, findLegalType(Aspect, Action));
}
bool isLegal(const MachineInstr &MI) const;
private:
- typedef DenseMap<std::pair<unsigned, LLT>, LegalizeAction> ActionMap;
+ typedef DenseMap<InstrAspect, LegalizeAction> ActionMap;
+ typedef DenseMap<std::pair<unsigned, LLT>, LegalizeAction> SIVActionMap;
ActionMap Actions;
- ActionMap ScalarInVectorActions;
+ SIVActionMap ScalarInVectorActions;
DenseMap<std::pair<unsigned, LLT>, uint16_t> MaxLegalVectorElts;
DenseMap<unsigned, LegalizeAction> DefaultActions;
bool TablesInitialized;
};
+
} // End namespace llvm.
#endif
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
index 7c3253dd36a..bd8374cb6b0 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
@@ -34,15 +34,15 @@ MachineLegalizeHelper::MachineLegalizeHelper(MachineFunction &MF)
MachineLegalizeHelper::LegalizeResult MachineLegalizeHelper::legalizeInstr(
MachineInstr &MI, const MachineLegalizer &Legalizer) {
auto Action = Legalizer.getAction(MI);
- switch (Action.first) {
+ switch (std::get<0>(Action)) {
case MachineLegalizer::Legal:
return AlreadyLegal;
case MachineLegalizer::NarrowScalar:
- return narrowScalar(MI, Action.second);
+ return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action));
case MachineLegalizer::WidenScalar:
- return widenScalar(MI, Action.second);
+ return widenScalar(MI, std::get<1>(Action), std::get<2>(Action));
case MachineLegalizer::FewerElements:
- return fewerElementsVector(MI, Action.second);
+ return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action));
default:
return UnableToLegalize;
}
@@ -63,7 +63,9 @@ void MachineLegalizeHelper::extractParts(unsigned Reg, LLT Ty, int NumParts,
}
MachineLegalizeHelper::LegalizeResult
-MachineLegalizeHelper::narrowScalar(MachineInstr &MI, LLT NarrowTy) {
+MachineLegalizeHelper::narrowScalar(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy) {
+ assert(TypeIdx == 0 && "don't know how to handle secondary types yet");
switch (MI.getOpcode()) {
default:
return UnableToLegalize;
@@ -103,7 +105,10 @@ MachineLegalizeHelper::narrowScalar(MachineInstr &MI, LLT NarrowTy) {
}
MachineLegalizeHelper::LegalizeResult
-MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
+MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
+ LLT WideTy) {
+ assert(TypeIdx == 0 && "don't know how to handle secondary types yet");
+
unsigned WideSize = WideTy.getSizeInBits();
MIRBuilder.setInstr(MI);
@@ -172,7 +177,9 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
}
MachineLegalizeHelper::LegalizeResult
-MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, LLT NarrowTy) {
+MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy) {
+ assert(TypeIdx == 0 && "don't know how to handle secondary types yet");
switch (MI.getOpcode()) {
default:
return UnableToLegalize;
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
index fa23627de7c..dd32b1fe10f 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
@@ -35,12 +35,12 @@ MachineLegalizer::MachineLegalizer() : TablesInitialized(false) {
void MachineLegalizer::computeTables() {
for (auto &Op : Actions) {
- LLT Ty = Op.first.second;
+ LLT Ty = Op.first.Type;
if (!Ty.isVector())
continue;
- auto &Entry =
- MaxLegalVectorElts[std::make_pair(Op.first.first, Ty.getElementType())];
+ auto &Entry = MaxLegalVectorElts[std::make_pair(Op.first.Opcode,
+ Ty.getElementType())];
Entry = std::max(Entry, Ty.getNumElements());
}
@@ -52,27 +52,30 @@ void MachineLegalizer::computeTables() {
// we have any hope of doing well with something like <13 x i3>. Even the common
// cases should do better than what we have now.
std::pair<MachineLegalizer::LegalizeAction, LLT>
-MachineLegalizer::getAction(unsigned Opcode, LLT Ty) const {
+MachineLegalizer::getAction(const InstrAspect &Aspect) const {
assert(TablesInitialized && "backend forgot to call computeTables");
// These *have* to be implemented for now, they're the fundamental basis of
// how everything else is transformed.
// FIXME: the long-term plan calls for expansion in terms of load/store (if
// they're not legal).
- if (Opcode == TargetOpcode::G_SEQUENCE || Opcode == TargetOpcode::G_EXTRACT)
- return std::make_pair(Legal, Ty);
+ if (Aspect.Opcode == TargetOpcode::G_SEQUENCE ||
+ Aspect.Opcode == TargetOpcode::G_EXTRACT)
+ return std::make_pair(Legal, Aspect.Type);
- auto ActionIt = Actions.find(std::make_pair(Opcode, Ty));
+ auto ActionIt = Actions.find(Aspect);
if (ActionIt != Actions.end())
- return findLegalAction(Opcode, Ty, ActionIt->second);
+ return findLegalAction(Aspect, ActionIt->second);
+ unsigned Opcode = Aspect.Opcode;
+ LLT Ty = Aspect.Type;
if (!Ty.isVector()) {
- auto DefaultAction = DefaultActions.find(Opcode);
+ auto DefaultAction = DefaultActions.find(Aspect.Opcode);
if (DefaultAction != DefaultActions.end() && DefaultAction->second == Legal)
return std::make_pair(Legal, Ty);
assert(DefaultAction->second == NarrowScalar && "unexpected default");
- return findLegalAction(Opcode, Ty, NarrowScalar);
+ return findLegalAction(Aspect, NarrowScalar);
}
LLT EltTy = Ty.getElementType();
@@ -81,13 +84,13 @@ MachineLegalizer::getAction(unsigned Opcode, LLT Ty) const {
auto ScalarAction = ScalarInVectorActions.find(std::make_pair(Opcode, EltTy));
if (ScalarAction != ScalarInVectorActions.end() &&
ScalarAction->second != Legal)
- return findLegalAction(Opcode, EltTy, ScalarAction->second);
+ return findLegalAction(Aspect, ScalarAction->second);
// The element type is legal in principle, but the number of elements is
// wrong.
auto MaxLegalElts = MaxLegalVectorElts.lookup(std::make_pair(Opcode, EltTy));
if (MaxLegalElts > NumElts)
- return findLegalAction(Opcode, Ty, MoreElements);
+ return findLegalAction(Aspect, MoreElements);
if (MaxLegalElts == 0) {
// Scalarize if there's no legal vector type, which is just a special case
@@ -95,41 +98,46 @@ MachineLegalizer::getAction(unsigned Opcode, LLT Ty) const {
return std::make_pair(FewerElements, EltTy);
}
- return findLegalAction(Opcode, Ty, FewerElements);
+ return findLegalAction(Aspect, FewerElements);
}
-std::pair<MachineLegalizer::LegalizeAction, LLT>
+std::tuple<MachineLegalizer::LegalizeAction, unsigned, LLT>
MachineLegalizer::getAction(const MachineInstr &MI) const {
- return getAction(MI.getOpcode(), MI.getType());
+ for (unsigned i = 0; i < MI.getNumTypes(); ++i) {
+ auto Action = getAction({MI.getOpcode(), i, MI.getType(i)});
+ if (Action.first != Legal)
+ return {Action.first, i, Action.second};
+ }
+ return {Legal, 0, LLT{}};
}
bool MachineLegalizer::isLegal(const MachineInstr &MI) const {
- return getAction(MI).first == Legal;
+ return std::get<0>(getAction(MI)) == Legal;
}
-LLT MachineLegalizer::findLegalType(unsigned Opcode, LLT Ty,
+LLT MachineLegalizer::findLegalType(const InstrAspect &Aspect,
LegalizeAction Action) const {
switch(Action) {
default:
llvm_unreachable("Cannot find legal type");
case Legal:
- return Ty;
+ return Aspect.Type;
case NarrowScalar: {
- return findLegalType(Opcode, Ty,
+ return findLegalType(Aspect,
[&](LLT Ty) -> LLT { return Ty.halfScalarSize(); });
}
case WidenScalar: {
- return findLegalType(Opcode, Ty, [&](LLT Ty) -> LLT {
+ return findLegalType(Aspect, [&](LLT Ty) -> LLT {
return Ty.getSizeInBits() < 8 ? LLT::scalar(8) : Ty.doubleScalarSize();
});
}
case FewerElements: {
- return findLegalType(Opcode, Ty,
+ return findLegalType(Aspect,
[&](LLT Ty) -> LLT { return Ty.halfElements(); });
}
case MoreElements: {
- return findLegalType(
- Opcode, Ty, [&](LLT Ty) -> LLT { return Ty.doubleElements(); });
+ return findLegalType(Aspect,
+ [&](LLT Ty) -> LLT { return Ty.doubleElements(); });
}
}
}
diff --git a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp
index 2a56ecd6b5b..901bbf1b9b9 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp
@@ -26,6 +26,7 @@ using namespace llvm;
AArch64MachineLegalizer::AArch64MachineLegalizer() {
using namespace TargetOpcode;
+ const LLT p0 = LLT::pointer(0);
const LLT s1 = LLT::scalar(1);
const LLT s8 = LLT::scalar(8);
const LLT s16 = LLT::scalar(16);
@@ -37,43 +38,49 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() {
for (auto BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) {
for (auto Ty : {s32, s64, v2s32, v4s32, v2s64})
- setAction(BinOp, Ty, Legal);
+ setAction({BinOp, Ty}, Legal);
for (auto Ty : {s8, s16})
- setAction(BinOp, Ty, WidenScalar);
+ setAction({BinOp, Ty}, WidenScalar);
}
for (auto BinOp : {G_SHL, G_LSHR, G_ASHR, G_SDIV, G_UDIV})
for (auto Ty : {s32, s64})
- setAction(BinOp, Ty, Legal);
+ setAction({BinOp, Ty}, Legal);
for (auto BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
for (auto Ty : {s32, s64})
- setAction(BinOp, Ty, Legal);
+ setAction({BinOp, Ty}, Legal);
for (auto MemOp : {G_LOAD, G_STORE}) {
for (auto Ty : {s8, s16, s32, s64})
- setAction(MemOp, Ty, Legal);
+ setAction({MemOp, Ty}, Legal);
- setAction(MemOp, s1, WidenScalar);
+ setAction({MemOp, s1}, WidenScalar);
+
+ // And everything's fine in addrspace 0.
+ setAction({MemOp, 1, p0}, Legal);
}
for (auto Ty : {s32, s64}) {
- setAction(TargetOpcode::G_CONSTANT, Ty, Legal);
- setAction(TargetOpcode::G_FCONSTANT, Ty, Legal);
+ setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
+ setAction({TargetOpcode::G_FCONSTANT, Ty}, Legal);
}
for (auto Ty : {s1, s8, s16})
- setAction(TargetOpcode::G_CONSTANT, Ty, WidenScalar);
+ setAction({TargetOpcode::G_CONSTANT, Ty}, WidenScalar);
+
+ setAction({TargetOpcode::G_FCONSTANT, s16}, WidenScalar);
- setAction(TargetOpcode::G_FCONSTANT, s16, WidenScalar);
+ setAction({G_BR, LLT::unsized()}, Legal);
- setAction(G_BR, LLT::unsized(), Legal);
+ setAction({G_FRAME_INDEX, p0}, Legal);
- setAction(G_FRAME_INDEX, LLT::pointer(0), Legal);
+ setAction({G_PTRTOINT, 0, s64}, Legal);
+ setAction({G_PTRTOINT, 1, p0}, Legal);
- setAction(G_PTRTOINT, s64, Legal);
- setAction(G_INTTOPTR, LLT::pointer(0), Legal);
+ setAction({G_INTTOPTR, 0, p0}, Legal);
+ setAction({G_INTTOPTR, 1, s64}, Legal);
computeTables();
}
diff --git a/llvm/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp b/llvm/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp
index 5f217623cac..946f3b4c0c9 100644
--- a/llvm/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp
@@ -52,51 +52,71 @@ namespace {
TEST(MachineLegalizerTest, ScalarRISC) {
+ using namespace TargetOpcode;
MachineLegalizer L;
// Typical RISCy set of operations based on AArch64.
- L.setAction(TargetOpcode::G_ADD, LLT::scalar(8), WidenScalar);
- L.setAction(TargetOpcode::G_ADD, LLT::scalar(16), WidenScalar);
- L.setAction(TargetOpcode::G_ADD, LLT::scalar(32), Legal);
- L.setAction(TargetOpcode::G_ADD, LLT::scalar(64), Legal);
+ L.setAction({G_ADD, LLT::scalar(8)}, WidenScalar);
+ L.setAction({G_ADD, LLT::scalar(16)}, WidenScalar);
+ L.setAction({G_ADD, LLT::scalar(32)}, Legal);
+ L.setAction({G_ADD, LLT::scalar(64)}, Legal);
L.computeTables();
// Check we infer the correct types and actually do what we're told.
- ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(8)),
+ ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(8)}),
std::make_pair(WidenScalar, LLT::scalar(32)));
- ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(16)),
+ ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(16)}),
std::make_pair(WidenScalar, LLT::scalar(32)));
- ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(32)),
+ ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(32)}),
std::make_pair(Legal, LLT::scalar(32)));
- ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(64)),
+ ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(64)}),
std::make_pair(Legal, LLT::scalar(64)));
// Make sure the default for over-sized types applies.
- ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(128)),
+ ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(128)}),
std::make_pair(NarrowScalar, LLT::scalar(64)));
}
TEST(MachineLegalizerTest, VectorRISC) {
+ using namespace TargetOpcode;
MachineLegalizer L;
// Typical RISCy set of operations based on ARM.
- L.setScalarInVectorAction(TargetOpcode::G_ADD, LLT::scalar(8), Legal);
- L.setScalarInVectorAction(TargetOpcode::G_ADD, LLT::scalar(16), Legal);
- L.setScalarInVectorAction(TargetOpcode::G_ADD, LLT::scalar(32), Legal);
-
- L.setAction(TargetOpcode::G_ADD, LLT::vector(8, 8), Legal);
- L.setAction(TargetOpcode::G_ADD, LLT::vector(16, 8), Legal);
- L.setAction(TargetOpcode::G_ADD, LLT::vector(4, 16), Legal);
- L.setAction(TargetOpcode::G_ADD, LLT::vector(8, 16), Legal);
- L.setAction(TargetOpcode::G_ADD, LLT::vector(2, 32), Legal);
- L.setAction(TargetOpcode::G_ADD, LLT::vector(4, 32), Legal);
+ L.setScalarInVectorAction(G_ADD, LLT::scalar(8), Legal);
+ L.setScalarInVectorAction(G_ADD, LLT::scalar(16), Legal);
+ L.setScalarInVectorAction(G_ADD, LLT::scalar(32), Legal);
+
+ L.setAction({G_ADD, LLT::vector(8, 8)}, Legal);
+ L.setAction({G_ADD, LLT::vector(16, 8)}, Legal);
+ L.setAction({G_ADD, LLT::vector(4, 16)}, Legal);
+ L.setAction({G_ADD, LLT::vector(8, 16)}, Legal);
+ L.setAction({G_ADD, LLT::vector(2, 32)}, Legal);
+ L.setAction({G_ADD, LLT::vector(4, 32)}, Legal);
L.computeTables();
// Check we infer the correct types and actually do what we're told for some
// simple cases.
- ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::vector(2, 8)),
+ ASSERT_EQ(L.getAction({G_ADD, LLT::vector(2, 8)}),
std::make_pair(MoreElements, LLT::vector(8, 8)));
- ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::vector(8, 8)),
+ ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 8)}),
std::make_pair(Legal, LLT::vector(8, 8)));
- ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::vector(8, 32)),
+ ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 32)}),
std::make_pair(FewerElements, LLT::vector(4, 32)));
}
+
+TEST(MachineLegalizerTest, MultipleTypes) {
+ using namespace TargetOpcode;
+ MachineLegalizer L;
+
+ // Typical RISCy set of operations based on AArch64.
+ L.setAction({G_PTRTOINT, 0, LLT::scalar(64)}, Legal);
+ L.setAction({G_PTRTOINT, 1, LLT::pointer(0)}, Legal);
+
+ L.setAction({G_PTRTOINT, 0, LLT::scalar(32)}, WidenScalar);
+ L.computeTables();
+
+ // Check we infer the correct types and actually do what we're told.
+ ASSERT_EQ(L.getAction({G_PTRTOINT, 0, LLT::scalar(64)}),
+ std::make_pair(Legal, LLT::scalar(64)));
+ ASSERT_EQ(L.getAction({G_PTRTOINT, 1, LLT::pointer(0)}),
+ std::make_pair(Legal, LLT::pointer(0)));
+}
}
OpenPOWER on IntegriCloud