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 v2p0 = LLT::fixed_vector(2, p0); 245 const LLT v3p0 = LLT::fixed_vector(3, p0); 246 const LLT v4p0 = LLT::fixed_vector(4, p0); 247 248 const LLT s1 = LLT::scalar(1); 249 const LLT v2s1 = LLT::fixed_vector(2, 1); 250 const LLT v4s1 = LLT::fixed_vector(4, 1); 251 252 { 253 LegalizerInfo LI; 254 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 255 256 LI.getActionDefinitionsBuilder(G_IMPLICIT_DEF) 257 .legalFor({v4s32, v4p0}) 258 .moreElementsToNextPow2(0); 259 LegacyInfo.computeTables(); 260 261 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {s32})); 262 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {v2s32})); 263 EXPECT_ACTION(MoreElements, 0, v4p0, LegalityQuery(G_IMPLICIT_DEF, {v3p0})); 264 EXPECT_ACTION(MoreElements, 0, v4s32, LegalityQuery(G_IMPLICIT_DEF, {v3s32})); 265 } 266 267 // Test minScalarOrElt 268 { 269 LegalizerInfo LI; 270 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 271 LI.getActionDefinitionsBuilder(G_OR) 272 .legalFor({s32}) 273 .minScalarOrElt(0, s32); 274 LegacyInfo.computeTables(); 275 276 EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16})); 277 EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_OR, {v2s16})); 278 } 279 280 // Test maxScalarOrELt 281 { 282 LegalizerInfo LI; 283 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 284 LI.getActionDefinitionsBuilder(G_AND) 285 .legalFor({s16}) 286 .maxScalarOrElt(0, s16); 287 LegacyInfo.computeTables(); 288 289 EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32})); 290 EXPECT_ACTION(NarrowScalar, 0, v2s16, LegalityQuery(G_AND, {v2s32})); 291 } 292 293 // Test clampScalarOrElt 294 { 295 LegalizerInfo LI; 296 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 297 LI.getActionDefinitionsBuilder(G_XOR) 298 .legalFor({s16}) 299 .clampScalarOrElt(0, s16, s32); 300 LegacyInfo.computeTables(); 301 302 EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64})); 303 EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8})); 304 305 // Make sure the number of elements is preserved. 306 EXPECT_ACTION(NarrowScalar, 0, v2s32, LegalityQuery(G_XOR, {v2s64})); 307 EXPECT_ACTION(WidenScalar, 0, v2s16, LegalityQuery(G_XOR, {v2s8})); 308 } 309 310 // Test minScalar 311 { 312 LegalizerInfo LI; 313 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 314 LI.getActionDefinitionsBuilder(G_OR) 315 .legalFor({s32}) 316 .minScalar(0, s32); 317 LegacyInfo.computeTables(); 318 319 // Only handle scalars, ignore vectors. 320 EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16})); 321 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_OR, {v2s16})); 322 } 323 324 // Test maxScalar 325 { 326 LegalizerInfo LI; 327 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 328 LI.getActionDefinitionsBuilder(G_AND) 329 .legalFor({s16}) 330 .maxScalar(0, s16); 331 LegacyInfo.computeTables(); 332 333 // Only handle scalars, ignore vectors. 334 EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32})); 335 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s32})); 336 } 337 338 // Test clampScalar 339 { 340 LegalizerInfo LI; 341 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 342 343 LI.getActionDefinitionsBuilder(G_XOR) 344 .legalFor({s16}) 345 .clampScalar(0, s16, s32); 346 LegacyInfo.computeTables(); 347 348 EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64})); 349 EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8})); 350 351 // Only handle scalars, ignore vectors. 352 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s64})); 353 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s8})); 354 } 355 356 // Test widenScalarOrEltToNextPow2 357 { 358 LegalizerInfo LI; 359 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 360 361 LI.getActionDefinitionsBuilder(G_AND) 362 .legalFor({s32}) 363 .widenScalarOrEltToNextPow2(0, 32); 364 LegacyInfo.computeTables(); 365 366 // Handle scalars and vectors 367 EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5})); 368 EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_AND, {v2s5})); 369 EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33})); 370 EXPECT_ACTION(WidenScalar, 0, v2s64, LegalityQuery(G_AND, {v2s33})); 371 } 372 373 // Test widenScalarToNextPow2 374 { 375 LegalizerInfo LI; 376 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 377 378 LI.getActionDefinitionsBuilder(G_AND) 379 .legalFor({s32}) 380 .widenScalarToNextPow2(0, 32); 381 LegacyInfo.computeTables(); 382 383 EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5})); 384 EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33})); 385 386 // Do nothing for vectors. 387 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s5})); 388 EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s33})); 389 } 390 391 // Test changeElementCountTo 392 { 393 LegalizerInfo LI; 394 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 395 396 // Type index form 397 LI.getActionDefinitionsBuilder(G_SELECT) 398 .moreElementsIf(isScalar(1), changeElementCountTo(1, 0)); 399 400 // Raw type form 401 LI.getActionDefinitionsBuilder(G_ADD) 402 .fewerElementsIf(typeIs(0, v4s32), changeElementCountTo(0, v2s32)) 403 .fewerElementsIf(typeIs(0, v8s32), changeElementCountTo(0, s32)) 404 .fewerElementsIf(typeIs(0, LLT::scalable_vector(4, 16)), 405 changeElementCountTo(0, LLT::scalable_vector(2, 16))) 406 .fewerElementsIf(typeIs(0, LLT::scalable_vector(8, 16)), 407 changeElementCountTo(0, s16)); 408 409 LegacyInfo.computeTables(); 410 411 EXPECT_ACTION(MoreElements, 1, v4s1, LegalityQuery(G_SELECT, {v4s32, s1})); 412 EXPECT_ACTION(MoreElements, 1, v2s1, LegalityQuery(G_SELECT, {v2s32, s1})); 413 EXPECT_ACTION(MoreElements, 1, v2s1, LegalityQuery(G_SELECT, {v2s32, s1})); 414 EXPECT_ACTION(MoreElements, 1, v4s1, LegalityQuery(G_SELECT, {v4p0, s1})); 415 416 EXPECT_ACTION(MoreElements, 1, LLT::scalable_vector(2, 1), 417 LegalityQuery(G_SELECT, {LLT::scalable_vector(2, 32), s1})); 418 EXPECT_ACTION(MoreElements, 1, LLT::scalable_vector(4, 1), 419 LegalityQuery(G_SELECT, {LLT::scalable_vector(4, 32), s1})); 420 EXPECT_ACTION(MoreElements, 1, LLT::scalable_vector(2, s1), 421 LegalityQuery(G_SELECT, {LLT::scalable_vector(2, p0), s1})); 422 423 EXPECT_ACTION(FewerElements, 0, v2s32, LegalityQuery(G_ADD, {v4s32})); 424 EXPECT_ACTION(FewerElements, 0, s32, LegalityQuery(G_ADD, {v8s32})); 425 426 EXPECT_ACTION(FewerElements, 0, LLT::scalable_vector(2, 16), 427 LegalityQuery(G_ADD, {LLT::scalable_vector(4, 16)})); 428 EXPECT_ACTION(FewerElements, 0, s16, 429 LegalityQuery(G_ADD, {LLT::scalable_vector(8, 16)})); 430 } 431 432 // Test minScalarEltSameAsIf 433 { 434 LegalizerInfo LI; 435 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 436 437 LI.getActionDefinitionsBuilder(G_SELECT).minScalarEltSameAsIf( 438 all(isVector(0), isVector(1)), 1, 0); 439 LegacyInfo.computeTables(); 440 LLT p1 = LLT::pointer(1, 32); 441 LLT v2p1 = LLT::fixed_vector(2, p1); 442 443 EXPECT_ACTION(WidenScalar, 1, v2s32, LegalityQuery(G_SELECT, {v2p0, v2s1})); 444 EXPECT_ACTION(WidenScalar, 1, v2s32, LegalityQuery(G_SELECT, {v2p1, v2s1})); 445 } 446 } 447 448 TEST(LegalizerInfoTest, MMOAlignment) { 449 using namespace TargetOpcode; 450 451 const LLT s32 = LLT::scalar(32); 452 const LLT p0 = LLT::pointer(0, 64); 453 454 { 455 LegalizerInfo LI; 456 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 457 LI.getActionDefinitionsBuilder(G_LOAD) 458 .legalForTypesWithMemDesc({{s32, p0, s32, 32}}); 459 460 LegacyInfo.computeTables(); 461 462 EXPECT_ACTION(Legal, 0, LLT(), 463 LegalityQuery(G_LOAD, {s32, p0}, 464 LegalityQuery::MemDesc{ 465 s32, 32, AtomicOrdering::NotAtomic})); 466 EXPECT_ACTION(Unsupported, 0, LLT(), 467 LegalityQuery(G_LOAD, {s32, p0}, 468 LegalityQuery::MemDesc{ 469 s32, 16, AtomicOrdering::NotAtomic })); 470 EXPECT_ACTION(Unsupported, 0, LLT(), 471 LegalityQuery(G_LOAD, {s32, p0}, 472 LegalityQuery::MemDesc{ 473 s32, 8, AtomicOrdering::NotAtomic})); 474 } 475 476 // Test that the maximum supported alignment value isn't truncated 477 { 478 // Maximum IR defined alignment in bytes. 479 const uint64_t MaxAlignment = UINT64_C(1) << 29; 480 const uint64_t MaxAlignInBits = 8 * MaxAlignment; 481 LegalizerInfo LI; 482 auto &LegacyInfo = LI.getLegacyLegalizerInfo(); 483 LI.getActionDefinitionsBuilder(G_LOAD) 484 .legalForTypesWithMemDesc({{s32, p0, s32, MaxAlignInBits}}); 485 486 LegacyInfo.computeTables(); 487 488 EXPECT_ACTION(Legal, 0, LLT(), 489 LegalityQuery(G_LOAD, {s32, p0}, 490 LegalityQuery::MemDesc{s32, 491 MaxAlignInBits, AtomicOrdering::NotAtomic})); 492 EXPECT_ACTION(Unsupported, 0, LLT(), 493 LegalityQuery(G_LOAD, {s32, p0}, 494 LegalityQuery::MemDesc{ 495 s32, 8, AtomicOrdering::NotAtomic })); 496 } 497 } 498 499 // This code sequence doesn't do anything, but it covers a previously uncovered 500 // codepath that used to crash in MSVC x86_32 debug mode. 501 TEST(LegalizerInfoTest, MSVCDebugMiscompile) { 502 const LLT S1 = LLT::scalar(1); 503 const LLT P0 = LLT::pointer(0, 32); 504 LegalizerInfo LI; 505 auto Builder = LI.getActionDefinitionsBuilder(TargetOpcode::G_PTRTOINT); 506 (void)Builder.legalForCartesianProduct({S1}, {P0}); 507 } 508