1 //===- llvm/unittest/CodeGen/GlobalISel/LegalizerInfoTest.cpp -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 11 #include "llvm/CodeGen/TargetOpcodes.h" 12 #include "gtest/gtest.h" 13 14 using namespace llvm; 15 16 // Define a couple of pretty printers to help debugging when things go wrong. 17 namespace llvm { 18 std::ostream & 19 operator<<(std::ostream &OS, const llvm::LegalizerInfo::LegalizeAction Act) { 20 switch (Act) { 21 case LegalizerInfo::Lower: OS << "Lower"; break; 22 case LegalizerInfo::Legal: OS << "Legal"; break; 23 case LegalizerInfo::NarrowScalar: OS << "NarrowScalar"; break; 24 case LegalizerInfo::WidenScalar: OS << "WidenScalar"; break; 25 case LegalizerInfo::FewerElements: OS << "FewerElements"; break; 26 case LegalizerInfo::MoreElements: OS << "MoreElements"; break; 27 case LegalizerInfo::Libcall: OS << "Libcall"; break; 28 case LegalizerInfo::Custom: OS << "Custom"; break; 29 case LegalizerInfo::Unsupported: OS << "Unsupported"; break; 30 case LegalizerInfo::NotFound: OS << "NotFound"; 31 } 32 return OS; 33 } 34 35 std::ostream & 36 operator<<(std::ostream &OS, const llvm::LLT Ty) { 37 std::string Repr; 38 raw_string_ostream SS{Repr}; 39 Ty.print(SS); 40 OS << SS.str(); 41 return OS; 42 } 43 } 44 45 namespace { 46 47 48 TEST(LegalizerInfoTest, ScalarRISC) { 49 using namespace TargetOpcode; 50 LegalizerInfo L; 51 // Typical RISCy set of operations based on AArch64. 52 for (unsigned Op : {G_ADD, G_SUB}) { 53 for (unsigned Size : {32, 64}) 54 L.setAction({Op, 0, LLT::scalar(Size)}, LegalizerInfo::Legal); 55 L.setLegalizeScalarToDifferentSizeStrategy( 56 Op, 0, LegalizerInfo::widenToLargerTypesAndNarrowToLargest); 57 } 58 59 L.computeTables(); 60 61 for (unsigned opcode : {G_ADD, G_SUB}) { 62 // Check we infer the correct types and actually do what we're told. 63 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(8)}}), 64 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(32))); 65 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(16)}}), 66 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(32))); 67 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(32)}}), 68 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{})); 69 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(64)}}), 70 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{})); 71 72 // Make sure the default for over-sized types applies. 73 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(128)}}), 74 LegalizerInfo::LegalizeActionStep(LegalizerInfo::NarrowScalar, 0, LLT::scalar(64))); 75 // Make sure we also handle unusual sizes 76 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(1)}}), 77 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(32))); 78 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(31)}}), 79 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(32))); 80 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(33)}}), 81 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(64))); 82 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(63)}}), 83 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(64))); 84 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(65)}}), 85 LegalizerInfo::LegalizeActionStep(LegalizerInfo::NarrowScalar, 0, LLT::scalar(64))); 86 } 87 } 88 89 TEST(LegalizerInfoTest, VectorRISC) { 90 using namespace TargetOpcode; 91 LegalizerInfo L; 92 // Typical RISCy set of operations based on ARM. 93 L.setAction({G_ADD, LLT::vector(8, 8)}, LegalizerInfo::Legal); 94 L.setAction({G_ADD, LLT::vector(16, 8)}, LegalizerInfo::Legal); 95 L.setAction({G_ADD, LLT::vector(4, 16)}, LegalizerInfo::Legal); 96 L.setAction({G_ADD, LLT::vector(8, 16)}, LegalizerInfo::Legal); 97 L.setAction({G_ADD, LLT::vector(2, 32)}, LegalizerInfo::Legal); 98 L.setAction({G_ADD, LLT::vector(4, 32)}, LegalizerInfo::Legal); 99 100 L.setLegalizeVectorElementToDifferentSizeStrategy( 101 G_ADD, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise); 102 103 L.setAction({G_ADD, 0, LLT::scalar(32)}, LegalizerInfo::Legal); 104 105 L.computeTables(); 106 107 // Check we infer the correct types and actually do what we're told for some 108 // simple cases. 109 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 8)}}), 110 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{})); 111 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 7)}}), 112 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::vector(8, 8))); 113 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(2, 8)}}), 114 LegalizerInfo::LegalizeActionStep(LegalizerInfo::MoreElements, 0, LLT::vector(8, 8))); 115 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 32)}}), 116 LegalizerInfo::LegalizeActionStep(LegalizerInfo::FewerElements, 0, LLT::vector(4, 32))); 117 // Check a few non-power-of-2 sizes: 118 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(3, 3)}}), 119 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::vector(3, 8))); 120 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(3, 8)}}), 121 LegalizerInfo::LegalizeActionStep(LegalizerInfo::MoreElements, 0, LLT::vector(8, 8))); 122 } 123 124 TEST(LegalizerInfoTest, MultipleTypes) { 125 using namespace TargetOpcode; 126 LegalizerInfo L; 127 LLT p0 = LLT::pointer(0, 64); 128 LLT s64 = LLT::scalar(64); 129 130 // Typical RISCy set of operations based on AArch64. 131 L.setAction({G_PTRTOINT, 0, s64}, LegalizerInfo::Legal); 132 L.setAction({G_PTRTOINT, 1, p0}, LegalizerInfo::Legal); 133 134 L.setLegalizeScalarToDifferentSizeStrategy( 135 G_PTRTOINT, 0, LegalizerInfo::widenToLargerTypesAndNarrowToLargest); 136 137 L.computeTables(); 138 139 // Check we infer the correct types and actually do what we're told. 140 ASSERT_EQ(L.getAction({G_PTRTOINT, {s64, p0}}), 141 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{})); 142 143 // Make sure we also handle unusual sizes 144 ASSERT_EQ( 145 L.getAction({G_PTRTOINT, {LLT::scalar(65), s64}}), 146 LegalizerInfo::LegalizeActionStep(LegalizerInfo::NarrowScalar, 0, s64)); 147 ASSERT_EQ( 148 L.getAction({G_PTRTOINT, {s64, LLT::pointer(0, 32)}}), 149 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Unsupported, 1, LLT::pointer(0, 32))); 150 } 151 152 TEST(LegalizerInfoTest, MultipleSteps) { 153 using namespace TargetOpcode; 154 LegalizerInfo L; 155 LLT s32 = LLT::scalar(32); 156 LLT s64 = LLT::scalar(64); 157 158 L.setLegalizeScalarToDifferentSizeStrategy( 159 G_UREM, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise); 160 L.setAction({G_UREM, 0, s32}, LegalizerInfo::Lower); 161 L.setAction({G_UREM, 0, s64}, LegalizerInfo::Lower); 162 163 L.computeTables(); 164 165 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(16)}}), 166 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(32))); 167 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(32)}}), 168 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Lower, 0, LLT::scalar(32))); 169 } 170 171 TEST(LegalizerInfoTest, SizeChangeStrategy) { 172 using namespace TargetOpcode; 173 LegalizerInfo L; 174 for (unsigned Size : {1, 8, 16, 32}) 175 L.setAction({G_UREM, 0, LLT::scalar(Size)}, LegalizerInfo::Legal); 176 177 L.setLegalizeScalarToDifferentSizeStrategy( 178 G_UREM, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise); 179 L.computeTables(); 180 181 // Check we infer the correct types and actually do what we're told. 182 for (unsigned Size : {1, 8, 16, 32}) { 183 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(Size)}}), 184 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{})); 185 } 186 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(2)}}), 187 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(8))); 188 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(7)}}), 189 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(8))); 190 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(9)}}), 191 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(16))); 192 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(17)}}), 193 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(32))); 194 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(31)}}), 195 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0, LLT::scalar(32))); 196 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(33)}}), 197 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Unsupported, 0, LLT::scalar(33))); 198 } 199 } 200