xref: /src/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1eb11fae6SDimitry Andric //===- lib/CodeGen/GlobalISel/LegalizerPredicates.cpp - Predicates --------===//
2eb11fae6SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6eb11fae6SDimitry Andric //
7eb11fae6SDimitry Andric //===----------------------------------------------------------------------===//
8eb11fae6SDimitry Andric //
9eb11fae6SDimitry Andric // A library of predicate factories to use for LegalityPredicate.
10eb11fae6SDimitry Andric //
11eb11fae6SDimitry Andric //===----------------------------------------------------------------------===//
12eb11fae6SDimitry Andric 
13b60736ecSDimitry Andric // Enable optimizations to work around MSVC debug mode bug in 32-bit:
14b60736ecSDimitry Andric // https://developercommunity.visualstudio.com/content/problem/1179643/msvc-copies-overaligned-non-trivially-copyable-par.html
15b60736ecSDimitry Andric // FIXME: Remove this when the issue is closed.
16b60736ecSDimitry Andric #if defined(_MSC_VER) && !defined(__clang__) && defined(_M_IX86)
17b60736ecSDimitry Andric // We have to disable runtime checks in order to enable optimizations. This is
18b60736ecSDimitry Andric // done for the entire file because the problem is actually observed in STL
19b60736ecSDimitry Andric // template functions.
20b60736ecSDimitry Andric #pragma runtime_checks("", off)
21b60736ecSDimitry Andric #pragma optimize("gs", on)
22b60736ecSDimitry Andric #endif
23b60736ecSDimitry Andric 
24eb11fae6SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
25eb11fae6SDimitry Andric 
26eb11fae6SDimitry Andric using namespace llvm;
27eb11fae6SDimitry Andric 
typeIs(unsigned TypeIdx,LLT Type)28eb11fae6SDimitry Andric LegalityPredicate LegalityPredicates::typeIs(unsigned TypeIdx, LLT Type) {
29eb11fae6SDimitry Andric   return
30eb11fae6SDimitry Andric       [=](const LegalityQuery &Query) { return Query.Types[TypeIdx] == Type; };
31eb11fae6SDimitry Andric }
32eb11fae6SDimitry Andric 
33eb11fae6SDimitry Andric LegalityPredicate
typeInSet(unsigned TypeIdx,std::initializer_list<LLT> TypesInit)34eb11fae6SDimitry Andric LegalityPredicates::typeInSet(unsigned TypeIdx,
35eb11fae6SDimitry Andric                               std::initializer_list<LLT> TypesInit) {
36eb11fae6SDimitry Andric   SmallVector<LLT, 4> Types = TypesInit;
37eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
38b60736ecSDimitry Andric     return llvm::is_contained(Types, Query.Types[TypeIdx]);
39eb11fae6SDimitry Andric   };
40eb11fae6SDimitry Andric }
41eb11fae6SDimitry Andric 
typePairInSet(unsigned TypeIdx0,unsigned TypeIdx1,std::initializer_list<std::pair<LLT,LLT>> TypesInit)42eb11fae6SDimitry Andric LegalityPredicate LegalityPredicates::typePairInSet(
43eb11fae6SDimitry Andric     unsigned TypeIdx0, unsigned TypeIdx1,
44eb11fae6SDimitry Andric     std::initializer_list<std::pair<LLT, LLT>> TypesInit) {
45eb11fae6SDimitry Andric   SmallVector<std::pair<LLT, LLT>, 4> Types = TypesInit;
46eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
47eb11fae6SDimitry Andric     std::pair<LLT, LLT> Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1]};
48b60736ecSDimitry Andric     return llvm::is_contained(Types, Match);
49eb11fae6SDimitry Andric   };
50eb11fae6SDimitry Andric }
51eb11fae6SDimitry Andric 
typePairAndMemDescInSet(unsigned TypeIdx0,unsigned TypeIdx1,unsigned MMOIdx,std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit)52e6d15924SDimitry Andric LegalityPredicate LegalityPredicates::typePairAndMemDescInSet(
53eb11fae6SDimitry Andric     unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
54e6d15924SDimitry Andric     std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit) {
55e6d15924SDimitry Andric   SmallVector<TypePairAndMemDesc, 4> TypesAndMemDesc = TypesAndMemDescInit;
56eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
57e6d15924SDimitry Andric     TypePairAndMemDesc Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1],
58344a3780SDimitry Andric                                 Query.MMODescrs[MMOIdx].MemoryTy,
59e6d15924SDimitry Andric                                 Query.MMODescrs[MMOIdx].AlignInBits};
60b60736ecSDimitry Andric     return llvm::any_of(TypesAndMemDesc,
61e6d15924SDimitry Andric                         [=](const TypePairAndMemDesc &Entry) -> bool {
62e6d15924SDimitry Andric                           return Match.isCompatible(Entry);
63b60736ecSDimitry Andric                         });
64eb11fae6SDimitry Andric   };
65eb11fae6SDimitry Andric }
66eb11fae6SDimitry Andric 
isScalar(unsigned TypeIdx)67eb11fae6SDimitry Andric LegalityPredicate LegalityPredicates::isScalar(unsigned TypeIdx) {
68eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
69eb11fae6SDimitry Andric     return Query.Types[TypeIdx].isScalar();
70eb11fae6SDimitry Andric   };
71eb11fae6SDimitry Andric }
72eb11fae6SDimitry Andric 
isVector(unsigned TypeIdx)73e6d15924SDimitry Andric LegalityPredicate LegalityPredicates::isVector(unsigned TypeIdx) {
74e6d15924SDimitry Andric   return [=](const LegalityQuery &Query) {
75e6d15924SDimitry Andric     return Query.Types[TypeIdx].isVector();
76e6d15924SDimitry Andric   };
77e6d15924SDimitry Andric }
78e6d15924SDimitry Andric 
isPointer(unsigned TypeIdx)79e6d15924SDimitry Andric LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx) {
80e6d15924SDimitry Andric   return [=](const LegalityQuery &Query) {
81e6d15924SDimitry Andric     return Query.Types[TypeIdx].isPointer();
82e6d15924SDimitry Andric   };
83e6d15924SDimitry Andric }
84e6d15924SDimitry Andric 
isPointer(unsigned TypeIdx,unsigned AddrSpace)85e6d15924SDimitry Andric LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx,
86e6d15924SDimitry Andric                                                 unsigned AddrSpace) {
87e6d15924SDimitry Andric   return [=](const LegalityQuery &Query) {
88e6d15924SDimitry Andric     LLT Ty = Query.Types[TypeIdx];
89e6d15924SDimitry Andric     return Ty.isPointer() && Ty.getAddressSpace() == AddrSpace;
90e6d15924SDimitry Andric   };
91e6d15924SDimitry Andric }
92e6d15924SDimitry Andric 
elementTypeIs(unsigned TypeIdx,LLT EltTy)93cfca06d7SDimitry Andric LegalityPredicate LegalityPredicates::elementTypeIs(unsigned TypeIdx,
94cfca06d7SDimitry Andric                                                     LLT EltTy) {
95cfca06d7SDimitry Andric   return [=](const LegalityQuery &Query) {
96cfca06d7SDimitry Andric     const LLT QueryTy = Query.Types[TypeIdx];
97cfca06d7SDimitry Andric     return QueryTy.isVector() && QueryTy.getElementType() == EltTy;
98cfca06d7SDimitry Andric   };
99cfca06d7SDimitry Andric }
100cfca06d7SDimitry Andric 
scalarNarrowerThan(unsigned TypeIdx,unsigned Size)101cfca06d7SDimitry Andric LegalityPredicate LegalityPredicates::scalarNarrowerThan(unsigned TypeIdx,
102eb11fae6SDimitry Andric                                                          unsigned Size) {
103eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
104e6d15924SDimitry Andric     const LLT QueryTy = Query.Types[TypeIdx];
105eb11fae6SDimitry Andric     return QueryTy.isScalar() && QueryTy.getSizeInBits() < Size;
106eb11fae6SDimitry Andric   };
107eb11fae6SDimitry Andric }
108eb11fae6SDimitry Andric 
scalarWiderThan(unsigned TypeIdx,unsigned Size)109cfca06d7SDimitry Andric LegalityPredicate LegalityPredicates::scalarWiderThan(unsigned TypeIdx,
110eb11fae6SDimitry Andric                                                       unsigned Size) {
111eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
112e6d15924SDimitry Andric     const LLT QueryTy = Query.Types[TypeIdx];
113eb11fae6SDimitry Andric     return QueryTy.isScalar() && QueryTy.getSizeInBits() > Size;
114eb11fae6SDimitry Andric   };
115eb11fae6SDimitry Andric }
116eb11fae6SDimitry Andric 
smallerThan(unsigned TypeIdx0,unsigned TypeIdx1)117cfca06d7SDimitry Andric LegalityPredicate LegalityPredicates::smallerThan(unsigned TypeIdx0,
118cfca06d7SDimitry Andric                                                   unsigned TypeIdx1) {
119cfca06d7SDimitry Andric   return [=](const LegalityQuery &Query) {
120cfca06d7SDimitry Andric     return Query.Types[TypeIdx0].getSizeInBits() <
121cfca06d7SDimitry Andric            Query.Types[TypeIdx1].getSizeInBits();
122cfca06d7SDimitry Andric   };
123cfca06d7SDimitry Andric }
124cfca06d7SDimitry Andric 
largerThan(unsigned TypeIdx0,unsigned TypeIdx1)125cfca06d7SDimitry Andric LegalityPredicate LegalityPredicates::largerThan(unsigned TypeIdx0,
126cfca06d7SDimitry Andric                                                   unsigned TypeIdx1) {
127cfca06d7SDimitry Andric   return [=](const LegalityQuery &Query) {
128cfca06d7SDimitry Andric     return Query.Types[TypeIdx0].getSizeInBits() >
129cfca06d7SDimitry Andric            Query.Types[TypeIdx1].getSizeInBits();
130cfca06d7SDimitry Andric   };
131cfca06d7SDimitry Andric }
132cfca06d7SDimitry Andric 
scalarOrEltNarrowerThan(unsigned TypeIdx,unsigned Size)133e6d15924SDimitry Andric LegalityPredicate LegalityPredicates::scalarOrEltNarrowerThan(unsigned TypeIdx,
134e6d15924SDimitry Andric                                                               unsigned Size) {
135e6d15924SDimitry Andric   return [=](const LegalityQuery &Query) {
136e6d15924SDimitry Andric     const LLT QueryTy = Query.Types[TypeIdx];
137e6d15924SDimitry Andric     return QueryTy.getScalarSizeInBits() < Size;
138e6d15924SDimitry Andric   };
139e6d15924SDimitry Andric }
140e6d15924SDimitry Andric 
scalarOrEltWiderThan(unsigned TypeIdx,unsigned Size)141e6d15924SDimitry Andric LegalityPredicate LegalityPredicates::scalarOrEltWiderThan(unsigned TypeIdx,
142e6d15924SDimitry Andric                                                            unsigned Size) {
143e6d15924SDimitry Andric   return [=](const LegalityQuery &Query) {
144e6d15924SDimitry Andric     const LLT QueryTy = Query.Types[TypeIdx];
145e6d15924SDimitry Andric     return QueryTy.getScalarSizeInBits() > Size;
146e6d15924SDimitry Andric   };
147e6d15924SDimitry Andric }
148e6d15924SDimitry Andric 
scalarOrEltSizeNotPow2(unsigned TypeIdx)149e6d15924SDimitry Andric LegalityPredicate LegalityPredicates::scalarOrEltSizeNotPow2(unsigned TypeIdx) {
150e6d15924SDimitry Andric   return [=](const LegalityQuery &Query) {
151e6d15924SDimitry Andric     const LLT QueryTy = Query.Types[TypeIdx];
152e6d15924SDimitry Andric     return !isPowerOf2_32(QueryTy.getScalarSizeInBits());
153e6d15924SDimitry Andric   };
154e6d15924SDimitry Andric }
155e6d15924SDimitry Andric 
sizeNotMultipleOf(unsigned TypeIdx,unsigned Size)156c0981da4SDimitry Andric LegalityPredicate LegalityPredicates::sizeNotMultipleOf(unsigned TypeIdx,
157c0981da4SDimitry Andric                                                         unsigned Size) {
158c0981da4SDimitry Andric   return [=](const LegalityQuery &Query) {
159c0981da4SDimitry Andric     const LLT QueryTy = Query.Types[TypeIdx];
160c0981da4SDimitry Andric     return QueryTy.isScalar() && QueryTy.getSizeInBits() % Size != 0;
161c0981da4SDimitry Andric   };
162c0981da4SDimitry Andric }
163c0981da4SDimitry Andric 
sizeNotPow2(unsigned TypeIdx)164eb11fae6SDimitry Andric LegalityPredicate LegalityPredicates::sizeNotPow2(unsigned TypeIdx) {
165eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
166e6d15924SDimitry Andric     const LLT QueryTy = Query.Types[TypeIdx];
1677fa27ce4SDimitry Andric     return QueryTy.isScalar() &&
1687fa27ce4SDimitry Andric            !llvm::has_single_bit<uint32_t>(QueryTy.getSizeInBits());
169eb11fae6SDimitry Andric   };
170eb11fae6SDimitry Andric }
171eb11fae6SDimitry Andric 
sizeIs(unsigned TypeIdx,unsigned Size)172cfca06d7SDimitry Andric LegalityPredicate LegalityPredicates::sizeIs(unsigned TypeIdx, unsigned Size) {
173cfca06d7SDimitry Andric   return [=](const LegalityQuery &Query) {
174cfca06d7SDimitry Andric     return Query.Types[TypeIdx].getSizeInBits() == Size;
175cfca06d7SDimitry Andric   };
176cfca06d7SDimitry Andric }
177cfca06d7SDimitry Andric 
sameSize(unsigned TypeIdx0,unsigned TypeIdx1)178e6d15924SDimitry Andric LegalityPredicate LegalityPredicates::sameSize(unsigned TypeIdx0,
179e6d15924SDimitry Andric                                                unsigned TypeIdx1) {
180e6d15924SDimitry Andric   return [=](const LegalityQuery &Query) {
181e6d15924SDimitry Andric     return Query.Types[TypeIdx0].getSizeInBits() ==
182e6d15924SDimitry Andric            Query.Types[TypeIdx1].getSizeInBits();
183e6d15924SDimitry Andric   };
184e6d15924SDimitry Andric }
185e6d15924SDimitry Andric 
memSizeInBytesNotPow2(unsigned MMOIdx)186eb11fae6SDimitry Andric LegalityPredicate LegalityPredicates::memSizeInBytesNotPow2(unsigned MMOIdx) {
187eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
1887fa27ce4SDimitry Andric     return !llvm::has_single_bit<uint32_t>(
1897fa27ce4SDimitry Andric         Query.MMODescrs[MMOIdx].MemoryTy.getSizeInBytes());
190eb11fae6SDimitry Andric   };
191eb11fae6SDimitry Andric }
192eb11fae6SDimitry Andric 
memSizeNotByteSizePow2(unsigned MMOIdx)193145449b1SDimitry Andric LegalityPredicate LegalityPredicates::memSizeNotByteSizePow2(unsigned MMOIdx) {
194145449b1SDimitry Andric   return [=](const LegalityQuery &Query) {
195145449b1SDimitry Andric     const LLT MemTy = Query.MMODescrs[MMOIdx].MemoryTy;
1967fa27ce4SDimitry Andric     return !MemTy.isByteSized() ||
1977fa27ce4SDimitry Andric            !llvm::has_single_bit<uint32_t>(MemTy.getSizeInBytes());
198145449b1SDimitry Andric   };
199145449b1SDimitry Andric }
200145449b1SDimitry Andric 
numElementsNotPow2(unsigned TypeIdx)201eb11fae6SDimitry Andric LegalityPredicate LegalityPredicates::numElementsNotPow2(unsigned TypeIdx) {
202eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
203e6d15924SDimitry Andric     const LLT QueryTy = Query.Types[TypeIdx];
204e6d15924SDimitry Andric     return QueryTy.isVector() && !isPowerOf2_32(QueryTy.getNumElements());
205eb11fae6SDimitry Andric   };
206eb11fae6SDimitry Andric }
207eb11fae6SDimitry Andric 
atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx,AtomicOrdering Ordering)208eb11fae6SDimitry Andric LegalityPredicate LegalityPredicates::atomicOrderingAtLeastOrStrongerThan(
209eb11fae6SDimitry Andric     unsigned MMOIdx, AtomicOrdering Ordering) {
210eb11fae6SDimitry Andric   return [=](const LegalityQuery &Query) {
211eb11fae6SDimitry Andric     return isAtLeastOrStrongerThan(Query.MMODescrs[MMOIdx].Ordering, Ordering);
212eb11fae6SDimitry Andric   };
213eb11fae6SDimitry Andric }
214