1 //===- llvm/unittest/CodeGen/GlobalISel/LegalizerInfoTest.cpp -------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 10 #include "llvm/CodeGen/TargetOpcodes.h" 11 #include "GISelMITest.h" 12 #include "gtest/gtest.h" 13 14 using namespace llvm; 15 using namespace LegalizeActions; 16 using namespace LegalityPredicates; 17 using namespace LegalizeMutations; 18 19 // Define a couple of pretty printers to help debugging when things go wrong. 20 namespace llvm { 21 std::ostream & 22 operator<<(std::ostream &OS, const LegalizeAction Act) { 23 switch (Act) { 24 case Lower: OS << "Lower"; break; 25 case Legal: OS << "Legal"; break; 26 case NarrowScalar: OS << "NarrowScalar"; break; 27 case WidenScalar: OS << "WidenScalar"; break; 28 case FewerElements: OS << "FewerElements"; break; 29 case MoreElements: OS << "MoreElements"; break; 30 case Libcall: OS << "Libcall"; break; 31 case Custom: OS << "Custom"; break; 32 case Bitcast: OS << "Bitcast"; break; 33 case Unsupported: OS << "Unsupported"; break; 34 case NotFound: OS << "NotFound"; break; 35 case UseLegacyRules: OS << "UseLegacyRules"; break; 36 } 37 return OS; 38 } 39 40 std::ostream &operator<<(std::ostream &OS, const llvm::LegalizeActionStep Ty) { 41 OS << "LegalizeActionStep(" << Ty.Action << ", " << Ty.TypeIdx << ", " 42 << Ty.NewType << ')'; 43 return OS; 44 } 45 } 46 47 namespace { 48 49 50 TEST(LegalizerInfoTest, ScalarRISC) { 51 using namespace TargetOpcode; 52 LegalizerInfo L; 53 auto &LegacyInfo = L.getLegacyLegalizerInfo(); 54 // Typical RISCy set of operations based on AArch64. 55 for (unsigned Op : {G_ADD, G_SUB}) { 56 for (unsigned Size : {32, 64}) 57 LegacyInfo.setAction({Op, 0, LLT::scalar(Size)}, 58 LegacyLegalizeActions::Legal); 59 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy( 60 Op, 0, LegacyLegalizerInfo::widenToLargerTypesAndNarrowToLargest); 61 } 62 63 LegacyInfo.computeTables(); 64 65 for (unsigned opcode : {G_ADD, G_SUB}) { 66 // Check we infer the correct types and actually do what we're told. 67 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(8)}}), 68 LegalizeActionStep(WidenScalar, 0, LLT::scalar(32))); 69 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(16)}}), 70 LegalizeActionStep(WidenScalar, 0, LLT::scalar(32))); 71 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(32)}}), 72 LegalizeActionStep(Legal, 0, LLT{})); 73 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(64)}}), 74 LegalizeActionStep(Legal, 0, LLT{})); 75 76 // Make sure the default for over-sized types applies. 77 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(128)}}), 78 LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64))); 79 // Make sure we also handle unusual sizes 80 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(1)}}), 81 LegalizeActionStep(WidenScalar, 0, LLT::scalar(32))); 82 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(31)}}), 83 LegalizeActionStep(WidenScalar, 0, LLT::scalar(32))); 84 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(33)}}), 85 LegalizeActionStep(WidenScalar, 0, LLT::scalar(64))); 86 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(63)}}), 87 LegalizeActionStep(WidenScalar, 0, LLT::scalar(64))); 88 EXPECT_EQ(L.getAction({opcode, {LLT::scalar(65)}}), 89 LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64))); 90 } 91 } 92 93 TEST(LegalizerInfoTest, VectorRISC) { 94 using namespace TargetOpcode; 95 LegalizerInfo L; 96 auto &LegacyInfo = L.getLegacyLegalizerInfo(); 97 // Typical RISCy set of operations based on ARM. 98 LegacyInfo.setAction({G_ADD, LLT::fixed_vector(8, 8)}, 99 LegacyLegalizeActions::Legal); 100 LegacyInfo.setAction({G_ADD, LLT::fixed_vector(16, 8)}, 101 LegacyLegalizeActions::Legal); 102 LegacyInfo.setAction({G_ADD, LLT::fixed_vector(4, 16)}, 103 LegacyLegalizeActions::Legal); 104 LegacyInfo.setAction({G_ADD, LLT::fixed_vector(8, 16)}, 105 LegacyLegalizeActions::Legal); 106 LegacyInfo.setAction({G_ADD, LLT::fixed_vector(2, 32)}, 107 LegacyLegalizeActions::Legal); 108 LegacyInfo.setAction({G_ADD, LLT::fixed_vector(4, 32)}, 109 LegacyLegalizeActions::Legal); 110 111 LegacyInfo.setLegalizeVectorElementToDifferentSizeStrategy( 112 G_ADD, 0, LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise); 113 114 LegacyInfo.setAction({G_ADD, 0, LLT::scalar(32)}, 115 LegacyLegalizeActions::Legal); 116 117 LegacyInfo.computeTables(); 118 119 // Check we infer the correct types and actually do what we're told for some 120 // simple cases. 121 EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(8, 8)}}), 122 LegalizeActionStep(Legal, 0, LLT{})); 123 EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(8, 7)}}), 124 LegalizeActionStep(WidenScalar, 0, LLT::fixed_vector(8, 8))); 125 EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(2, 8)}}), 126 LegalizeActionStep(MoreElements, 0, LLT::fixed_vector(8, 8))); 127 EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(8, 32)}}), 128 LegalizeActionStep(FewerElements, 0, LLT::fixed_vector(4, 32))); 129 // Check a few non-power-of-2 sizes: 130 EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(3, 3)}}), 131 LegalizeActionStep(WidenScalar, 0, LLT::fixed_vector(3, 8))); 132 EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(3, 8)}}), 133 LegalizeActionStep(MoreElements, 0, LLT::fixed_vector(8, 8))); 134 } 135 136 TEST(LegalizerInfoTest, MultipleTypes) { 137 using namespace TargetOpcode; 138 LegalizerInfo L; 139 auto &LegacyInfo = L.getLegacyLegalizerInfo(); 140 LLT p0 = LLT::pointer(0, 64); 141 LLT s64 = LLT::scalar(64); 142 143 // Typical RISCy set of operations based on AArch64. 144 LegacyInfo.setAction({G_PTRTOINT, 0, s64}, LegacyLegalizeActions::Legal); 145 LegacyInfo.setAction({G_PTRTOINT, 1, p0}, LegacyLegalizeActions::Legal); 146 147 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy( 148 G_PTRTOINT, 0, LegacyLegalizerInfo::widenToLargerTypesAndNarrowToLargest); 149 150 LegacyInfo.computeTables(); 151 152 // Check we infer the correct types and actually do what we're told. 153 EXPECT_EQ(L.getAction({G_PTRTOINT, {s64, p0}}), 154 LegalizeActionStep(Legal, 0, LLT{})); 155 156 // Make sure we also handle unusual sizes 157 EXPECT_EQ( 158 L.getAction({G_PTRTOINT, {LLT::scalar(65), s64}}), 159 LegalizeActionStep(NarrowScalar, 0, s64)); 160 EXPECT_EQ( 161 L.getAction({G_PTRTOINT, {s64, LLT::pointer(0, 32)}}), 162 LegalizeActionStep(Unsupported, 1, LLT::pointer(0, 32))); 163 } 164 165 TEST(LegalizerInfoTest, MultipleSteps) { 166 using namespace TargetOpcode; 167 LegalizerInfo L; 168 auto &LegacyInfo = L.getLegacyLegalizerInfo(); 169 LLT s32 = LLT::scalar(32); 170 LLT s64 = LLT::scalar(64); 171 172 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy( 173 G_UREM, 0, LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise); 174 LegacyInfo.setAction({G_UREM, 0, s32}, LegacyLegalizeActions::Lower); 175 LegacyInfo.setAction({G_UREM, 0, s64}, LegacyLegalizeActions::Lower); 176 177 LegacyInfo.computeTables(); 178 179 EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(16)}}), 180 LegalizeActionStep(WidenScalar, 0, LLT::scalar(32))); 181 EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(32)}}), 182 LegalizeActionStep(Lower, 0, LLT::scalar(32))); 183 } 184 185 TEST(LegalizerInfoTest, SizeChangeStrategy) { 186 using namespace TargetOpcode; 187 LegalizerInfo L; 188 auto &LegacyInfo = L.getLegacyLegalizerInfo(); 189 for (unsigned Size : {1, 8, 16, 32}) 190 LegacyInfo.setAction({G_UREM, 0, LLT::scalar(Size)}, 191 LegacyLegalizeActions::Legal); 192 193 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy( 194 G_UREM, 0, LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise); 195 LegacyInfo.computeTables(); 196 197 // Check we infer the correct types and actually do what we're told. 198 for (unsigned Size : {1, 8, 16, 32}) { 199 EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(Size)}}), 200 LegalizeActionStep(Legal, 0, LLT{})); 201 } 202 EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(2)}}), 203 LegalizeActionStep(WidenScalar, 0, LLT::scalar(8))); 204 EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(7)}}), 205 LegalizeActionStep(WidenScalar, 0, LLT::scalar(8))); 206 EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(9)}}), 207 LegalizeActionStep(WidenScalar, 0, LLT::scalar(16))); 208 EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(17)}}), 209 LegalizeActionStep(WidenScalar, 0, LLT::scalar(32))); 210 EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(31)}}), 211 LegalizeActionStep(WidenScalar, 0, LLT::scalar(32))); 212 EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(33)}}), 213 LegalizeActionStep(Unsupported, 0, LLT::scalar(33))); 214 } 215 } 216 217 #define EXPECT_ACTION(Action, Index, Type, Query) \ 218 do { \ 219 auto A = LI.getAction(Query); \ 220 EXPECT_EQ(LegalizeActionStep(Action, Index, Type), A) << A; \ 221 } while (0) 222 223 TEST(LegalizerInfoTest, RuleSets) { 224 using namespace TargetOpcode; 225 226 const LLT s5 = LLT::scalar(5); 227 const LLT s8 = LLT::scalar(8); 228 const LLT s16 = LLT::scalar(16); 229 const LLT s32 = LLT::scalar(32); 230 const LLT s33 = LLT::scalar(33); 231 const LLT s64 = LLT::scalar(64); 232 233 const LLT v2s5 = LLT::fixed_vector(2, 5); 234 const LLT v2s8 = LLT::fixed_vector(2, 8); 235 const LLT v2s16 = LLT::fixed_vector(2, 16); 236 const LLT v2s32 = LLT::fixed_vector(2, 32); 237 const LLT v3s32 = LLT::fixed_vector(3, 32); 238 const LLT v4s32 = LLT::fixed_vector(4, 32); 239 const LLT v8s32 = LLT::fixed_vector(8, 32); 240 const LLT v2s33 = LLT::fixed_vector(2, 33); 241 const LLT v2s64 = LLT::fixed_vector(2, 64); 242 243 const LLT p0 = LLT::pointer(0, 32); 244 const LLT v3p0 = LLT::fixed_vector(3, p0); 245 const LLT v4p0 = LLT::fixed_vector(4, p0); 246 247 const LLT s1 = LLT::scalar(1); 248 const LLT v2s1 = LLT::fixed_vector(2, 1); 249 const LLT v4s1 = LLT::fixed_vector(4, 1); 250 251 { 252 LegalizerInfo LI; 253 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 254 255 LI.getActionDefinitionsBuilder(G_IMPLICIT_DEF) 256 .legalFor({v4s32, v4p0}) 257 .moreElementsToNextPow2(0); 258 LegacyInfo.computeTables(); 259 260 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {s32})); 261 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {v2s32})); 262 EXPECT_ACTION(MoreElements, 0, v4p0, LegalityQuery(G_IMPLICIT_DEF, {v3p0})); 263 EXPECT_ACTION(MoreElements, 0, v4s32, LegalityQuery(G_IMPLICIT_DEF, {v3s32})); 264 } 265 266 // Test minScalarOrElt 267 { 268 LegalizerInfo LI; 269 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 270 LI.getActionDefinitionsBuilder(G_OR) 271 .legalFor({s32}) 272 .minScalarOrElt(0, s32); 273 LegacyInfo.computeTables(); 274 275 EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16})); 276 EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_OR, {v2s16})); 277 } 278 279 // Test maxScalarOrELt 280 { 281 LegalizerInfo LI; 282 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 283 LI.getActionDefinitionsBuilder(G_AND) 284 .legalFor({s16}) 285 .maxScalarOrElt(0, s16); 286 LegacyInfo.computeTables(); 287 288 EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32})); 289 EXPECT_ACTION(NarrowScalar, 0, v2s16, LegalityQuery(G_AND, {v2s32})); 290 } 291 292 // Test clampScalarOrElt 293 { 294 LegalizerInfo LI; 295 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 296 LI.getActionDefinitionsBuilder(G_XOR) 297 .legalFor({s16}) 298 .clampScalarOrElt(0, s16, s32); 299 LegacyInfo.computeTables(); 300 301 EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64})); 302 EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8})); 303 304 // Make sure the number of elements is preserved. 305 EXPECT_ACTION(NarrowScalar, 0, v2s32, LegalityQuery(G_XOR, {v2s64})); 306 EXPECT_ACTION(WidenScalar, 0, v2s16, LegalityQuery(G_XOR, {v2s8})); 307 } 308 309 // Test minScalar 310 { 311 LegalizerInfo LI; 312 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 313 LI.getActionDefinitionsBuilder(G_OR) 314 .legalFor({s32}) 315 .minScalar(0, s32); 316 LegacyInfo.computeTables(); 317 318 // Only handle scalars, ignore vectors. 319 EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16})); 320 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_OR, {v2s16})); 321 } 322 323 // Test maxScalar 324 { 325 LegalizerInfo LI; 326 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 327 LI.getActionDefinitionsBuilder(G_AND) 328 .legalFor({s16}) 329 .maxScalar(0, s16); 330 LegacyInfo.computeTables(); 331 332 // Only handle scalars, ignore vectors. 333 EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32})); 334 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s32})); 335 } 336 337 // Test clampScalar 338 { 339 LegalizerInfo LI; 340 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 341 342 LI.getActionDefinitionsBuilder(G_XOR) 343 .legalFor({s16}) 344 .clampScalar(0, s16, s32); 345 LegacyInfo.computeTables(); 346 347 EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64})); 348 EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8})); 349 350 // Only handle scalars, ignore vectors. 351 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s64})); 352 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s8})); 353 } 354 355 // Test widenScalarOrEltToNextPow2 356 { 357 LegalizerInfo LI; 358 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 359 360 LI.getActionDefinitionsBuilder(G_AND) 361 .legalFor({s32}) 362 .widenScalarOrEltToNextPow2(0, 32); 363 LegacyInfo.computeTables(); 364 365 // Handle scalars and vectors 366 EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5})); 367 EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_AND, {v2s5})); 368 EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33})); 369 EXPECT_ACTION(WidenScalar, 0, v2s64, LegalityQuery(G_AND, {v2s33})); 370 } 371 372 // Test widenScalarToNextPow2 373 { 374 LegalizerInfo LI; 375 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 376 377 LI.getActionDefinitionsBuilder(G_AND) 378 .legalFor({s32}) 379 .widenScalarToNextPow2(0, 32); 380 LegacyInfo.computeTables(); 381 382 EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5})); 383 EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33})); 384 385 // Do nothing for vectors. 386 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s5})); 387 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s33})); 388 } 389 390 // Test changeElementCountTo 391 { 392 LegalizerInfo LI; 393 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 394 395 // Type index form 396 LI.getActionDefinitionsBuilder(G_SELECT) 397 .moreElementsIf(isScalar(1), changeElementCountTo(1, 0)); 398 399 // Raw type form 400 LI.getActionDefinitionsBuilder(G_ADD) 401 .fewerElementsIf(typeIs(0, v4s32), changeElementCountTo(0, v2s32)) 402 .fewerElementsIf(typeIs(0, v8s32), changeElementCountTo(0, s32)) 403 .fewerElementsIf(typeIs(0, LLT::scalable_vector(4, 16)), 404 changeElementCountTo(0, LLT::scalable_vector(2, 16))) 405 .fewerElementsIf(typeIs(0, LLT::scalable_vector(8, 16)), 406 changeElementCountTo(0, s16)); 407 408 LegacyInfo.computeTables(); 409 410 EXPECT_ACTION(MoreElements, 1, v4s1, LegalityQuery(G_SELECT, {v4s32, s1})); 411 EXPECT_ACTION(MoreElements, 1, v2s1, LegalityQuery(G_SELECT, {v2s32, s1})); 412 EXPECT_ACTION(MoreElements, 1, v2s1, LegalityQuery(G_SELECT, {v2s32, s1})); 413 EXPECT_ACTION(MoreElements, 1, v4s1, LegalityQuery(G_SELECT, {v4p0, s1})); 414 415 EXPECT_ACTION(MoreElements, 1, LLT::scalable_vector(2, 1), 416 LegalityQuery(G_SELECT, {LLT::scalable_vector(2, 32), s1})); 417 EXPECT_ACTION(MoreElements, 1, LLT::scalable_vector(4, 1), 418 LegalityQuery(G_SELECT, {LLT::scalable_vector(4, 32), s1})); 419 EXPECT_ACTION(MoreElements, 1, LLT::scalable_vector(2, s1), 420 LegalityQuery(G_SELECT, {LLT::scalable_vector(2, p0), s1})); 421 422 EXPECT_ACTION(FewerElements, 0, v2s32, LegalityQuery(G_ADD, {v4s32})); 423 EXPECT_ACTION(FewerElements, 0, s32, LegalityQuery(G_ADD, {v8s32})); 424 425 EXPECT_ACTION(FewerElements, 0, LLT::scalable_vector(2, 16), 426 LegalityQuery(G_ADD, {LLT::scalable_vector(4, 16)})); 427 EXPECT_ACTION(FewerElements, 0, s16, 428 LegalityQuery(G_ADD, {LLT::scalable_vector(8, 16)})); 429 } 430 } 431 432 TEST(LegalizerInfoTest, MMOAlignment) { 433 using namespace TargetOpcode; 434 435 const LLT s32 = LLT::scalar(32); 436 const LLT p0 = LLT::pointer(0, 64); 437 438 { 439 LegalizerInfo LI; 440 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 441 LI.getActionDefinitionsBuilder(G_LOAD) 442 .legalForTypesWithMemDesc({{s32, p0, s32, 32}}); 443 444 LegacyInfo.computeTables(); 445 446 EXPECT_ACTION(Legal, 0, LLT(), 447 LegalityQuery(G_LOAD, {s32, p0}, 448 LegalityQuery::MemDesc{ 449 s32, 32, AtomicOrdering::NotAtomic})); 450 EXPECT_ACTION(Unsupported, 0, LLT(), 451 LegalityQuery(G_LOAD, {s32, p0}, 452 LegalityQuery::MemDesc{ 453 s32, 16, AtomicOrdering::NotAtomic })); 454 EXPECT_ACTION(Unsupported, 0, LLT(), 455 LegalityQuery(G_LOAD, {s32, p0}, 456 LegalityQuery::MemDesc{ 457 s32, 8, AtomicOrdering::NotAtomic})); 458 } 459 460 // Test that the maximum supported alignment value isn't truncated 461 { 462 // Maximum IR defined alignment in bytes. 463 const uint64_t MaxAlignment = UINT64_C(1) << 29; 464 const uint64_t MaxAlignInBits = 8 * MaxAlignment; 465 LegalizerInfo LI; 466 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 467 LI.getActionDefinitionsBuilder(G_LOAD) 468 .legalForTypesWithMemDesc({{s32, p0, s32, MaxAlignInBits}}); 469 470 LegacyInfo.computeTables(); 471 472 EXPECT_ACTION(Legal, 0, LLT(), 473 LegalityQuery(G_LOAD, {s32, p0}, 474 LegalityQuery::MemDesc{s32, 475 MaxAlignInBits, AtomicOrdering::NotAtomic})); 476 EXPECT_ACTION(Unsupported, 0, LLT(), 477 LegalityQuery(G_LOAD, {s32, p0}, 478 LegalityQuery::MemDesc{ 479 s32, 8, AtomicOrdering::NotAtomic })); 480 } 481 } 482 483 // This code sequence doesn't do anything, but it covers a previously uncovered 484 // codepath that used to crash in MSVC x86_32 debug mode. 485 TEST(LegalizerInfoTest, MSVCDebugMiscompile) { 486 const LLT S1 = LLT::scalar(1); 487 const LLT P0 = LLT::pointer(0, 32); 488 LegalizerInfo LI; 489 auto Builder = LI.getActionDefinitionsBuilder(TargetOpcode::G_PTRTOINT); 490 (void)Builder.legalForCartesianProduct({S1}, {P0}); 491 } 492