179cb839fSDaniel Sanders //===- lib/CodeGen/GlobalISel/LegalizerPredicates.cpp - Predicates --------===//
279cb839fSDaniel Sanders //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
679cb839fSDaniel Sanders //
779cb839fSDaniel Sanders //===----------------------------------------------------------------------===//
879cb839fSDaniel Sanders //
979cb839fSDaniel Sanders // A library of predicate factories to use for LegalityPredicate.
1079cb839fSDaniel Sanders //
1179cb839fSDaniel Sanders //===----------------------------------------------------------------------===//
1279cb839fSDaniel Sanders
132c73bef7SReid Kleckner // Enable optimizations to work around MSVC debug mode bug in 32-bit:
144e3edef4SReid Kleckner // https://developercommunity.visualstudio.com/content/problem/1179643/msvc-copies-overaligned-non-trivially-copyable-par.html
154e3edef4SReid Kleckner // FIXME: Remove this when the issue is closed.
164e3edef4SReid Kleckner #if defined(_MSC_VER) && !defined(__clang__) && defined(_M_IX86)
174e3edef4SReid Kleckner // We have to disable runtime checks in order to enable optimizations. This is
184e3edef4SReid Kleckner // done for the entire file because the problem is actually observed in STL
194e3edef4SReid Kleckner // template functions.
204e3edef4SReid Kleckner #pragma runtime_checks("", off)
214e3edef4SReid Kleckner #pragma optimize("gs", on)
224e3edef4SReid Kleckner #endif
234e3edef4SReid Kleckner
2479cb839fSDaniel Sanders #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
2579cb839fSDaniel Sanders
2679cb839fSDaniel Sanders using namespace llvm;
2779cb839fSDaniel Sanders
typeIs(unsigned TypeIdx,LLT Type)28bdeb880dSDaniel Sanders LegalityPredicate LegalityPredicates::typeIs(unsigned TypeIdx, LLT Type) {
29bdeb880dSDaniel Sanders return
30bdeb880dSDaniel Sanders [=](const LegalityQuery &Query) { return Query.Types[TypeIdx] == Type; };
3179cb839fSDaniel Sanders }
3279cb839fSDaniel Sanders
3379cb839fSDaniel Sanders LegalityPredicate
typeInSet(unsigned TypeIdx,std::initializer_list<LLT> TypesInit)3479cb839fSDaniel Sanders LegalityPredicates::typeInSet(unsigned TypeIdx,
3579cb839fSDaniel Sanders std::initializer_list<LLT> TypesInit) {
3679cb839fSDaniel Sanders SmallVector<LLT, 4> Types = TypesInit;
3779cb839fSDaniel Sanders return [=](const LegalityQuery &Query) {
38902cbcd5SKazu Hirata return llvm::is_contained(Types, Query.Types[TypeIdx]);
3979cb839fSDaniel Sanders };
4079cb839fSDaniel Sanders }
4179cb839fSDaniel Sanders
typePairInSet(unsigned TypeIdx0,unsigned TypeIdx1,std::initializer_list<std::pair<LLT,LLT>> TypesInit)4279cb839fSDaniel Sanders LegalityPredicate LegalityPredicates::typePairInSet(
4379cb839fSDaniel Sanders unsigned TypeIdx0, unsigned TypeIdx1,
4479cb839fSDaniel Sanders std::initializer_list<std::pair<LLT, LLT>> TypesInit) {
4579cb839fSDaniel Sanders SmallVector<std::pair<LLT, LLT>, 4> Types = TypesInit;
4679cb839fSDaniel Sanders return [=](const LegalityQuery &Query) {
4779cb839fSDaniel Sanders std::pair<LLT, LLT> Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1]};
48902cbcd5SKazu Hirata return llvm::is_contained(Types, Match);
4979cb839fSDaniel Sanders };
5079cb839fSDaniel Sanders }
5179cb839fSDaniel Sanders
typePairAndMemDescInSet(unsigned TypeIdx0,unsigned TypeIdx1,unsigned MMOIdx,std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit)52530d05e9SMatt Arsenault LegalityPredicate LegalityPredicates::typePairAndMemDescInSet(
5327fe8a50SDaniel Sanders unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
54530d05e9SMatt Arsenault std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit) {
55530d05e9SMatt Arsenault SmallVector<TypePairAndMemDesc, 4> TypesAndMemDesc = TypesAndMemDescInit;
5627fe8a50SDaniel Sanders return [=](const LegalityQuery &Query) {
57530d05e9SMatt Arsenault TypePairAndMemDesc Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1],
5828f2f662SMatt Arsenault Query.MMODescrs[MMOIdx].MemoryTy,
59530d05e9SMatt Arsenault Query.MMODescrs[MMOIdx].AlignInBits};
60df812115SKazu Hirata return llvm::any_of(TypesAndMemDesc,
61530d05e9SMatt Arsenault [=](const TypePairAndMemDesc &Entry) -> bool {
62530d05e9SMatt Arsenault return Match.isCompatible(Entry);
63df812115SKazu Hirata });
6427fe8a50SDaniel Sanders };
6527fe8a50SDaniel Sanders }
6627fe8a50SDaniel Sanders
isScalar(unsigned TypeIdx)6779cb839fSDaniel Sanders LegalityPredicate LegalityPredicates::isScalar(unsigned TypeIdx) {
6879cb839fSDaniel Sanders return [=](const LegalityQuery &Query) {
6979cb839fSDaniel Sanders return Query.Types[TypeIdx].isScalar();
7079cb839fSDaniel Sanders };
7179cb839fSDaniel Sanders }
7279cb839fSDaniel Sanders
isVector(unsigned TypeIdx)73990f5077SMatt Arsenault LegalityPredicate LegalityPredicates::isVector(unsigned TypeIdx) {
74990f5077SMatt Arsenault return [=](const LegalityQuery &Query) {
75990f5077SMatt Arsenault return Query.Types[TypeIdx].isVector();
76990f5077SMatt Arsenault };
77990f5077SMatt Arsenault }
78990f5077SMatt Arsenault
isPointer(unsigned TypeIdx)79a5195829SMatt Arsenault LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx) {
80a5195829SMatt Arsenault return [=](const LegalityQuery &Query) {
81a5195829SMatt Arsenault return Query.Types[TypeIdx].isPointer();
82a5195829SMatt Arsenault };
83a5195829SMatt Arsenault }
84a5195829SMatt Arsenault
isPointer(unsigned TypeIdx,unsigned AddrSpace)85a5195829SMatt Arsenault LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx,
86a5195829SMatt Arsenault unsigned AddrSpace) {
87a5195829SMatt Arsenault return [=](const LegalityQuery &Query) {
88a5195829SMatt Arsenault LLT Ty = Query.Types[TypeIdx];
89a5195829SMatt Arsenault return Ty.isPointer() && Ty.getAddressSpace() == AddrSpace;
90a5195829SMatt Arsenault };
91a5195829SMatt Arsenault }
92a5195829SMatt Arsenault
elementTypeIs(unsigned TypeIdx,LLT EltTy)93e13c84c3SMatt Arsenault LegalityPredicate LegalityPredicates::elementTypeIs(unsigned TypeIdx,
94e13c84c3SMatt Arsenault LLT EltTy) {
95e13c84c3SMatt Arsenault return [=](const LegalityQuery &Query) {
96e13c84c3SMatt Arsenault const LLT QueryTy = Query.Types[TypeIdx];
97e13c84c3SMatt Arsenault return QueryTy.isVector() && QueryTy.getElementType() == EltTy;
98e13c84c3SMatt Arsenault };
99e13c84c3SMatt Arsenault }
100e13c84c3SMatt Arsenault
scalarNarrowerThan(unsigned TypeIdx,unsigned Size)101e13c84c3SMatt Arsenault LegalityPredicate LegalityPredicates::scalarNarrowerThan(unsigned TypeIdx,
10279cb839fSDaniel Sanders unsigned Size) {
10379cb839fSDaniel Sanders return [=](const LegalityQuery &Query) {
10491be65beSMatt Arsenault const LLT QueryTy = Query.Types[TypeIdx];
10579cb839fSDaniel Sanders return QueryTy.isScalar() && QueryTy.getSizeInBits() < Size;
10679cb839fSDaniel Sanders };
10779cb839fSDaniel Sanders }
10879cb839fSDaniel Sanders
scalarWiderThan(unsigned TypeIdx,unsigned Size)109e13c84c3SMatt Arsenault LegalityPredicate LegalityPredicates::scalarWiderThan(unsigned TypeIdx,
11079cb839fSDaniel Sanders unsigned Size) {
11179cb839fSDaniel Sanders return [=](const LegalityQuery &Query) {
11291be65beSMatt Arsenault const LLT QueryTy = Query.Types[TypeIdx];
11379cb839fSDaniel Sanders return QueryTy.isScalar() && QueryTy.getSizeInBits() > Size;
11479cb839fSDaniel Sanders };
11579cb839fSDaniel Sanders }
11679cb839fSDaniel Sanders
smallerThan(unsigned TypeIdx0,unsigned TypeIdx1)117e13c84c3SMatt Arsenault LegalityPredicate LegalityPredicates::smallerThan(unsigned TypeIdx0,
118e13c84c3SMatt Arsenault unsigned TypeIdx1) {
119e13c84c3SMatt Arsenault return [=](const LegalityQuery &Query) {
120e13c84c3SMatt Arsenault return Query.Types[TypeIdx0].getSizeInBits() <
121e13c84c3SMatt Arsenault Query.Types[TypeIdx1].getSizeInBits();
122e13c84c3SMatt Arsenault };
123e13c84c3SMatt Arsenault }
124e13c84c3SMatt Arsenault
largerThan(unsigned TypeIdx0,unsigned TypeIdx1)125e13c84c3SMatt Arsenault LegalityPredicate LegalityPredicates::largerThan(unsigned TypeIdx0,
126e13c84c3SMatt Arsenault unsigned TypeIdx1) {
127e13c84c3SMatt Arsenault return [=](const LegalityQuery &Query) {
128e13c84c3SMatt Arsenault return Query.Types[TypeIdx0].getSizeInBits() >
129e13c84c3SMatt Arsenault Query.Types[TypeIdx1].getSizeInBits();
130e13c84c3SMatt Arsenault };
131e13c84c3SMatt Arsenault }
132e13c84c3SMatt Arsenault
scalarOrEltNarrowerThan(unsigned TypeIdx,unsigned Size)13391be65beSMatt Arsenault LegalityPredicate LegalityPredicates::scalarOrEltNarrowerThan(unsigned TypeIdx,
13491be65beSMatt Arsenault unsigned Size) {
13591be65beSMatt Arsenault return [=](const LegalityQuery &Query) {
13691be65beSMatt Arsenault const LLT QueryTy = Query.Types[TypeIdx];
13791be65beSMatt Arsenault return QueryTy.getScalarSizeInBits() < Size;
13891be65beSMatt Arsenault };
13991be65beSMatt Arsenault }
14091be65beSMatt Arsenault
scalarOrEltWiderThan(unsigned TypeIdx,unsigned Size)14191be65beSMatt Arsenault LegalityPredicate LegalityPredicates::scalarOrEltWiderThan(unsigned TypeIdx,
14291be65beSMatt Arsenault unsigned Size) {
14391be65beSMatt Arsenault return [=](const LegalityQuery &Query) {
14491be65beSMatt Arsenault const LLT QueryTy = Query.Types[TypeIdx];
14591be65beSMatt Arsenault return QueryTy.getScalarSizeInBits() > Size;
14691be65beSMatt Arsenault };
14791be65beSMatt Arsenault }
14891be65beSMatt Arsenault
scalarOrEltSizeNotPow2(unsigned TypeIdx)14991be65beSMatt Arsenault LegalityPredicate LegalityPredicates::scalarOrEltSizeNotPow2(unsigned TypeIdx) {
15091be65beSMatt Arsenault return [=](const LegalityQuery &Query) {
15191be65beSMatt Arsenault const LLT QueryTy = Query.Types[TypeIdx];
15291be65beSMatt Arsenault return !isPowerOf2_32(QueryTy.getScalarSizeInBits());
15391be65beSMatt Arsenault };
15491be65beSMatt Arsenault }
15591be65beSMatt Arsenault
sizeNotMultipleOf(unsigned TypeIdx,unsigned Size)1566c4b634dSMirko Brkusanin LegalityPredicate LegalityPredicates::sizeNotMultipleOf(unsigned TypeIdx,
1576c4b634dSMirko Brkusanin unsigned Size) {
1586c4b634dSMirko Brkusanin return [=](const LegalityQuery &Query) {
1596c4b634dSMirko Brkusanin const LLT QueryTy = Query.Types[TypeIdx];
1606c4b634dSMirko Brkusanin return QueryTy.isScalar() && QueryTy.getSizeInBits() % Size != 0;
1616c4b634dSMirko Brkusanin };
1626c4b634dSMirko Brkusanin }
1636c4b634dSMirko Brkusanin
sizeNotPow2(unsigned TypeIdx)16479cb839fSDaniel Sanders LegalityPredicate LegalityPredicates::sizeNotPow2(unsigned TypeIdx) {
16579cb839fSDaniel Sanders return [=](const LegalityQuery &Query) {
16691be65beSMatt Arsenault const LLT QueryTy = Query.Types[TypeIdx];
16779cb839fSDaniel Sanders return QueryTy.isScalar() && !isPowerOf2_32(QueryTy.getSizeInBits());
16879cb839fSDaniel Sanders };
16979cb839fSDaniel Sanders }
17079cb839fSDaniel Sanders
sizeIs(unsigned TypeIdx,unsigned Size)171ef3e8312SMatt Arsenault LegalityPredicate LegalityPredicates::sizeIs(unsigned TypeIdx, unsigned Size) {
172ef3e8312SMatt Arsenault return [=](const LegalityQuery &Query) {
173ef3e8312SMatt Arsenault return Query.Types[TypeIdx].getSizeInBits() == Size;
174ef3e8312SMatt Arsenault };
175ef3e8312SMatt Arsenault }
176ef3e8312SMatt Arsenault
sameSize(unsigned TypeIdx0,unsigned TypeIdx1)177cbaada6bSMatt Arsenault LegalityPredicate LegalityPredicates::sameSize(unsigned TypeIdx0,
178cbaada6bSMatt Arsenault unsigned TypeIdx1) {
179cbaada6bSMatt Arsenault return [=](const LegalityQuery &Query) {
180cbaada6bSMatt Arsenault return Query.Types[TypeIdx0].getSizeInBits() ==
181cbaada6bSMatt Arsenault Query.Types[TypeIdx1].getSizeInBits();
182cbaada6bSMatt Arsenault };
183cbaada6bSMatt Arsenault }
184cbaada6bSMatt Arsenault
memSizeInBytesNotPow2(unsigned MMOIdx)18527fe8a50SDaniel Sanders LegalityPredicate LegalityPredicates::memSizeInBytesNotPow2(unsigned MMOIdx) {
18627fe8a50SDaniel Sanders return [=](const LegalityQuery &Query) {
18728f2f662SMatt Arsenault return !isPowerOf2_32(Query.MMODescrs[MMOIdx].MemoryTy.getSizeInBytes());
18827fe8a50SDaniel Sanders };
18927fe8a50SDaniel Sanders }
19027fe8a50SDaniel Sanders
memSizeNotByteSizePow2(unsigned MMOIdx)191*d1f97a34SMatt Arsenault LegalityPredicate LegalityPredicates::memSizeNotByteSizePow2(unsigned MMOIdx) {
192*d1f97a34SMatt Arsenault return [=](const LegalityQuery &Query) {
193*d1f97a34SMatt Arsenault const LLT MemTy = Query.MMODescrs[MMOIdx].MemoryTy;
194*d1f97a34SMatt Arsenault return !MemTy.isByteSized() || !isPowerOf2_32(MemTy.getSizeInBytes());
195*d1f97a34SMatt Arsenault };
196*d1f97a34SMatt Arsenault }
197*d1f97a34SMatt Arsenault
numElementsNotPow2(unsigned TypeIdx)19879cb839fSDaniel Sanders LegalityPredicate LegalityPredicates::numElementsNotPow2(unsigned TypeIdx) {
19979cb839fSDaniel Sanders return [=](const LegalityQuery &Query) {
20007238286SMatt Arsenault const LLT QueryTy = Query.Types[TypeIdx];
20107238286SMatt Arsenault return QueryTy.isVector() && !isPowerOf2_32(QueryTy.getNumElements());
20279cb839fSDaniel Sanders };
20379cb839fSDaniel Sanders }
204bdeb880dSDaniel Sanders
atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx,AtomicOrdering Ordering)205bdeb880dSDaniel Sanders LegalityPredicate LegalityPredicates::atomicOrderingAtLeastOrStrongerThan(
206bdeb880dSDaniel Sanders unsigned MMOIdx, AtomicOrdering Ordering) {
207bdeb880dSDaniel Sanders return [=](const LegalityQuery &Query) {
208bdeb880dSDaniel Sanders return isAtLeastOrStrongerThan(Query.MMODescrs[MMOIdx].Ordering, Ordering);
209bdeb880dSDaniel Sanders };
210bdeb880dSDaniel Sanders }
211