10b57cec5SDimitry Andric //===- lib/CodeGen/GlobalISel/LegalizerPredicates.cpp - Predicates --------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // A library of predicate factories to use for LegalityPredicate. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 13e8d8bef9SDimitry Andric // Enable optimizations to work around MSVC debug mode bug in 32-bit: 14e8d8bef9SDimitry Andric // https://developercommunity.visualstudio.com/content/problem/1179643/msvc-copies-overaligned-non-trivially-copyable-par.html 15e8d8bef9SDimitry Andric // FIXME: Remove this when the issue is closed. 16e8d8bef9SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__) && defined(_M_IX86) 17e8d8bef9SDimitry Andric // We have to disable runtime checks in order to enable optimizations. This is 18e8d8bef9SDimitry Andric // done for the entire file because the problem is actually observed in STL 19e8d8bef9SDimitry Andric // template functions. 20e8d8bef9SDimitry Andric #pragma runtime_checks("", off) 21e8d8bef9SDimitry Andric #pragma optimize("gs", on) 22e8d8bef9SDimitry Andric #endif 23e8d8bef9SDimitry Andric 240b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric using namespace llvm; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::typeIs(unsigned TypeIdx, LLT Type) { 290b57cec5SDimitry Andric return 300b57cec5SDimitry Andric [=](const LegalityQuery &Query) { return Query.Types[TypeIdx] == Type; }; 310b57cec5SDimitry Andric } 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric LegalityPredicate 340b57cec5SDimitry Andric LegalityPredicates::typeInSet(unsigned TypeIdx, 350b57cec5SDimitry Andric std::initializer_list<LLT> TypesInit) { 360b57cec5SDimitry Andric SmallVector<LLT, 4> Types = TypesInit; 370b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 38e8d8bef9SDimitry Andric return llvm::is_contained(Types, Query.Types[TypeIdx]); 390b57cec5SDimitry Andric }; 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::typePairInSet( 430b57cec5SDimitry Andric unsigned TypeIdx0, unsigned TypeIdx1, 440b57cec5SDimitry Andric std::initializer_list<std::pair<LLT, LLT>> TypesInit) { 450b57cec5SDimitry Andric SmallVector<std::pair<LLT, LLT>, 4> Types = TypesInit; 460b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 470b57cec5SDimitry Andric std::pair<LLT, LLT> Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1]}; 48e8d8bef9SDimitry Andric return llvm::is_contained(Types, Match); 490b57cec5SDimitry Andric }; 500b57cec5SDimitry Andric } 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::typePairAndMemDescInSet( 530b57cec5SDimitry Andric unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, 540b57cec5SDimitry Andric std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit) { 550b57cec5SDimitry Andric SmallVector<TypePairAndMemDesc, 4> TypesAndMemDesc = TypesAndMemDescInit; 560b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 570b57cec5SDimitry Andric TypePairAndMemDesc Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1], 58fe6060f1SDimitry Andric Query.MMODescrs[MMOIdx].MemoryTy, 590b57cec5SDimitry Andric Query.MMODescrs[MMOIdx].AlignInBits}; 60e8d8bef9SDimitry Andric return llvm::any_of(TypesAndMemDesc, 610b57cec5SDimitry Andric [=](const TypePairAndMemDesc &Entry) -> bool { 620b57cec5SDimitry Andric return Match.isCompatible(Entry); 63e8d8bef9SDimitry Andric }); 640b57cec5SDimitry Andric }; 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::isScalar(unsigned TypeIdx) { 680b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 690b57cec5SDimitry Andric return Query.Types[TypeIdx].isScalar(); 700b57cec5SDimitry Andric }; 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::isVector(unsigned TypeIdx) { 740b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 750b57cec5SDimitry Andric return Query.Types[TypeIdx].isVector(); 760b57cec5SDimitry Andric }; 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx) { 800b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 810b57cec5SDimitry Andric return Query.Types[TypeIdx].isPointer(); 820b57cec5SDimitry Andric }; 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx, 860b57cec5SDimitry Andric unsigned AddrSpace) { 870b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 880b57cec5SDimitry Andric LLT Ty = Query.Types[TypeIdx]; 890b57cec5SDimitry Andric return Ty.isPointer() && Ty.getAddressSpace() == AddrSpace; 900b57cec5SDimitry Andric }; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 935ffd83dbSDimitry Andric LegalityPredicate LegalityPredicates::elementTypeIs(unsigned TypeIdx, 945ffd83dbSDimitry Andric LLT EltTy) { 955ffd83dbSDimitry Andric return [=](const LegalityQuery &Query) { 965ffd83dbSDimitry Andric const LLT QueryTy = Query.Types[TypeIdx]; 975ffd83dbSDimitry Andric return QueryTy.isVector() && QueryTy.getElementType() == EltTy; 985ffd83dbSDimitry Andric }; 995ffd83dbSDimitry Andric } 1005ffd83dbSDimitry Andric 1015ffd83dbSDimitry Andric LegalityPredicate LegalityPredicates::scalarNarrowerThan(unsigned TypeIdx, 1020b57cec5SDimitry Andric unsigned Size) { 1030b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 1040b57cec5SDimitry Andric const LLT QueryTy = Query.Types[TypeIdx]; 1050b57cec5SDimitry Andric return QueryTy.isScalar() && QueryTy.getSizeInBits() < Size; 1060b57cec5SDimitry Andric }; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1095ffd83dbSDimitry Andric LegalityPredicate LegalityPredicates::scalarWiderThan(unsigned TypeIdx, 1100b57cec5SDimitry Andric unsigned Size) { 1110b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 1120b57cec5SDimitry Andric const LLT QueryTy = Query.Types[TypeIdx]; 1130b57cec5SDimitry Andric return QueryTy.isScalar() && QueryTy.getSizeInBits() > Size; 1140b57cec5SDimitry Andric }; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1175ffd83dbSDimitry Andric LegalityPredicate LegalityPredicates::smallerThan(unsigned TypeIdx0, 1185ffd83dbSDimitry Andric unsigned TypeIdx1) { 1195ffd83dbSDimitry Andric return [=](const LegalityQuery &Query) { 1205ffd83dbSDimitry Andric return Query.Types[TypeIdx0].getSizeInBits() < 1215ffd83dbSDimitry Andric Query.Types[TypeIdx1].getSizeInBits(); 1225ffd83dbSDimitry Andric }; 1235ffd83dbSDimitry Andric } 1245ffd83dbSDimitry Andric 1255ffd83dbSDimitry Andric LegalityPredicate LegalityPredicates::largerThan(unsigned TypeIdx0, 1265ffd83dbSDimitry Andric unsigned TypeIdx1) { 1275ffd83dbSDimitry Andric return [=](const LegalityQuery &Query) { 1285ffd83dbSDimitry Andric return Query.Types[TypeIdx0].getSizeInBits() > 1295ffd83dbSDimitry Andric Query.Types[TypeIdx1].getSizeInBits(); 1305ffd83dbSDimitry Andric }; 1315ffd83dbSDimitry Andric } 1325ffd83dbSDimitry Andric 1330b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::scalarOrEltNarrowerThan(unsigned TypeIdx, 1340b57cec5SDimitry Andric unsigned Size) { 1350b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 1360b57cec5SDimitry Andric const LLT QueryTy = Query.Types[TypeIdx]; 1370b57cec5SDimitry Andric return QueryTy.getScalarSizeInBits() < Size; 1380b57cec5SDimitry Andric }; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::scalarOrEltWiderThan(unsigned TypeIdx, 1420b57cec5SDimitry Andric unsigned Size) { 1430b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 1440b57cec5SDimitry Andric const LLT QueryTy = Query.Types[TypeIdx]; 1450b57cec5SDimitry Andric return QueryTy.getScalarSizeInBits() > Size; 1460b57cec5SDimitry Andric }; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::scalarOrEltSizeNotPow2(unsigned TypeIdx) { 1500b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 1510b57cec5SDimitry Andric const LLT QueryTy = Query.Types[TypeIdx]; 1520b57cec5SDimitry Andric return !isPowerOf2_32(QueryTy.getScalarSizeInBits()); 1530b57cec5SDimitry Andric }; 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric 156349cc55cSDimitry Andric LegalityPredicate LegalityPredicates::sizeNotMultipleOf(unsigned TypeIdx, 157349cc55cSDimitry Andric unsigned Size) { 158349cc55cSDimitry Andric return [=](const LegalityQuery &Query) { 159349cc55cSDimitry Andric const LLT QueryTy = Query.Types[TypeIdx]; 160349cc55cSDimitry Andric return QueryTy.isScalar() && QueryTy.getSizeInBits() % Size != 0; 161349cc55cSDimitry Andric }; 162349cc55cSDimitry Andric } 163349cc55cSDimitry Andric 1640b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::sizeNotPow2(unsigned TypeIdx) { 1650b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 1660b57cec5SDimitry Andric const LLT QueryTy = Query.Types[TypeIdx]; 1670b57cec5SDimitry Andric return QueryTy.isScalar() && !isPowerOf2_32(QueryTy.getSizeInBits()); 1680b57cec5SDimitry Andric }; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1715ffd83dbSDimitry Andric LegalityPredicate LegalityPredicates::sizeIs(unsigned TypeIdx, unsigned Size) { 1725ffd83dbSDimitry Andric return [=](const LegalityQuery &Query) { 1735ffd83dbSDimitry Andric return Query.Types[TypeIdx].getSizeInBits() == Size; 1745ffd83dbSDimitry Andric }; 1755ffd83dbSDimitry Andric } 1765ffd83dbSDimitry Andric 1770b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::sameSize(unsigned TypeIdx0, 1780b57cec5SDimitry Andric unsigned TypeIdx1) { 1790b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 1800b57cec5SDimitry Andric return Query.Types[TypeIdx0].getSizeInBits() == 1810b57cec5SDimitry Andric Query.Types[TypeIdx1].getSizeInBits(); 1820b57cec5SDimitry Andric }; 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::memSizeInBytesNotPow2(unsigned MMOIdx) { 1860b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 187fe6060f1SDimitry Andric return !isPowerOf2_32(Query.MMODescrs[MMOIdx].MemoryTy.getSizeInBytes()); 1880b57cec5SDimitry Andric }; 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 19181ad6265SDimitry Andric LegalityPredicate LegalityPredicates::memSizeNotByteSizePow2(unsigned MMOIdx) { 19281ad6265SDimitry Andric return [=](const LegalityQuery &Query) { 19381ad6265SDimitry Andric const LLT MemTy = Query.MMODescrs[MMOIdx].MemoryTy; 19481ad6265SDimitry Andric return !MemTy.isByteSized() || !isPowerOf2_32(MemTy.getSizeInBytes()); 19581ad6265SDimitry Andric }; 19681ad6265SDimitry Andric } 19781ad6265SDimitry Andric 1980b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::numElementsNotPow2(unsigned TypeIdx) { 1990b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 2000b57cec5SDimitry Andric const LLT QueryTy = Query.Types[TypeIdx]; 2010b57cec5SDimitry Andric return QueryTy.isVector() && !isPowerOf2_32(QueryTy.getNumElements()); 2020b57cec5SDimitry Andric }; 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric LegalityPredicate LegalityPredicates::atomicOrderingAtLeastOrStrongerThan( 2060b57cec5SDimitry Andric unsigned MMOIdx, AtomicOrdering Ordering) { 2070b57cec5SDimitry Andric return [=](const LegalityQuery &Query) { 2080b57cec5SDimitry Andric return isAtLeastOrStrongerThan(Query.MMODescrs[MMOIdx].Ordering, Ordering); 2090b57cec5SDimitry Andric }; 2100b57cec5SDimitry Andric } 211