1 //===- LegalizerHelperTest.cpp 2 //-----------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "GISelMITest.h" 11 12 using namespace LegalizeActions; 13 using namespace LegalizeMutations; 14 using namespace LegalityPredicates; 15 16 namespace { 17 18 class DummyGISelObserver : public GISelChangeObserver { 19 public: 20 void changingInstr(MachineInstr &MI) override {} 21 void changedInstr(MachineInstr &MI) override {} 22 void createdInstr(MachineInstr &MI) override {} 23 void erasingInstr(MachineInstr &MI) override {} 24 }; 25 26 // Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom, 27 // in which case it becomes CTTZ_ZERO_UNDEF with select. 28 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ0) { 29 setUp(); 30 if (!TM) 31 return; 32 33 // Declare your legalization info 34 DefineLegalizerInfo(A, { 35 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s32, s64}}); 36 }); 37 // Build Instr 38 auto MIBCTTZ = 39 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(32)}, {Copies[0]}); 40 AInfo Info(MF->getSubtarget()); 41 DummyGISelObserver Observer; 42 LegalizerHelper Helper(*MF, Info, Observer, B); 43 // Perform Legalization 44 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 45 Helper.lower(*MIBCTTZ, 0, LLT::scalar(64))); 46 47 auto CheckStr = R"( 48 CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF %0 49 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 50 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]] 51 CHECK: [[SIXTY4:%[0-9]+]]:_(s32) = G_CONSTANT i32 64 52 CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]] 53 )"; 54 55 // Check 56 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 57 } 58 59 // CTTZ expansion in terms of CTLZ 60 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ1) { 61 setUp(); 62 if (!TM) 63 return; 64 65 // Declare your legalization info 66 DefineLegalizerInfo(A, { 67 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s64, s64}}); 68 }); 69 // Build Instr 70 auto MIBCTTZ = 71 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]}); 72 AInfo Info(MF->getSubtarget()); 73 DummyGISelObserver Observer; 74 LegalizerHelper Helper(*MF, Info, Observer, B); 75 // Perform Legalization 76 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == 77 LegalizerHelper::LegalizeResult::Legalized); 78 79 auto CheckStr = R"( 80 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1 81 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]] 82 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]] 83 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_ 84 CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64 85 CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_ 86 CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_ 87 )"; 88 89 // Check 90 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 91 } 92 93 // CTLZ scalar narrowing 94 TEST_F(AArch64GISelMITest, NarrowScalarCTLZ) { 95 setUp(); 96 if (!TM) 97 return; 98 99 // Declare your legalization info 100 DefineLegalizerInfo(A, { 101 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s32, s32}}); 102 }); 103 // Build Instr 104 auto CTLZ = 105 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(32)}, {Copies[0]}); 106 AInfo Info(MF->getSubtarget()); 107 DummyGISelObserver Observer; 108 LegalizerHelper Helper(*MF, Info, Observer, B); 109 // Perform Legalization 110 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 111 Helper.narrowScalar(*CTLZ, 1, LLT::scalar(32))); 112 113 auto CheckStr = R"( 114 CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64) 115 CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 116 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_HI]]:_(s32), [[ZERO]]:_ 117 CHECK: [[CTLZ_LO:%[0-9]+]]:_(s32) = G_CTLZ [[UNMERGE_LO]]:_(s32) 118 CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32 119 CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTLZ_LO]]:_, [[THIRTYTWO]]:_ 120 CHECK: [[CTLZ_HI:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[UNMERGE_HI]]:_(s32) 121 CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTLZ_HI]]:_ 122 )"; 123 124 // Check 125 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 126 } 127 128 // CTTZ scalar narrowing 129 TEST_F(AArch64GISelMITest, NarrowScalarCTTZ) { 130 setUp(); 131 if (!TM) 132 return; 133 134 // Declare your legalization info 135 DefineLegalizerInfo(A, { 136 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s32, s64}}); 137 }); 138 // Build Instr 139 auto CTTZ = 140 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(32)}, {Copies[0]}); 141 AInfo Info(MF->getSubtarget()); 142 DummyGISelObserver Observer; 143 LegalizerHelper Helper(*MF, Info, Observer, B); 144 // Perform Legalization 145 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 146 Helper.narrowScalar(*CTTZ, 1, LLT::scalar(32))); 147 148 auto CheckStr = R"( 149 CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64) 150 CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 151 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_LO]]:_(s32), [[ZERO]]:_ 152 CHECK: [[CTTZ_HI:%[0-9]+]]:_(s32) = G_CTTZ [[UNMERGE_HI]]:_(s32) 153 CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32 154 CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTTZ_HI]]:_, [[THIRTYTWO]]:_ 155 CHECK: [[CTTZ_LO:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[UNMERGE_LO]]:_(s32) 156 CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTTZ_LO]]:_ 157 )"; 158 159 // Check 160 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 161 } 162 163 // CTTZ expansion in terms of CTPOP 164 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ2) { 165 setUp(); 166 if (!TM) 167 return; 168 169 // Declare your legalization info 170 DefineLegalizerInfo(A, { 171 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s64, s64}}); 172 }); 173 // Build 174 auto MIBCTTZ = 175 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]}); 176 AInfo Info(MF->getSubtarget()); 177 DummyGISelObserver Observer; 178 LegalizerHelper Helper(*MF, Info, Observer, B); 179 180 B.setInsertPt(*EntryMBB, MIBCTTZ->getIterator()); 181 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == 182 LegalizerHelper::LegalizeResult::Legalized); 183 184 auto CheckStr = R"( 185 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1 186 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]] 187 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]] 188 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_ 189 CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]] 190 )"; 191 192 // Check 193 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 194 } 195 196 // CTPOP widening. 197 TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP1) { 198 setUp(); 199 if (!TM) 200 return; 201 202 // Declare your legalization info 203 DefineLegalizerInfo(A, { 204 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}}); 205 }); 206 207 // Build 208 // Trunc it to s8. 209 LLT s8{LLT::scalar(8)}; 210 LLT s16{LLT::scalar(16)}; 211 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 212 auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s16}, {MIBTrunc}); 213 AInfo Info(MF->getSubtarget()); 214 DummyGISelObserver Observer; 215 LegalizerHelper Helper(*MF, Info, Observer, B); 216 B.setInstr(*MIBCTPOP); 217 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 218 Helper.widenScalar(*MIBCTPOP, 1, s16)); 219 220 auto CheckStr = R"( 221 CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64) 222 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8) 223 CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]] 224 CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[CTPOP]]:_(s16) 225 )"; 226 227 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 228 } 229 230 // Test a strange case where the result is wider than the source 231 TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP2) { 232 setUp(); 233 if (!TM) 234 return; 235 236 // Declare your legalization info 237 DefineLegalizerInfo(A, { 238 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s32, s16}}); 239 }); 240 241 // Build 242 // Trunc it to s8. 243 LLT s8{LLT::scalar(8)}; 244 LLT s16{LLT::scalar(16)}; 245 LLT s32{LLT::scalar(32)}; 246 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 247 auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s32}, {MIBTrunc}); 248 AInfo Info(MF->getSubtarget()); 249 DummyGISelObserver Observer; 250 LegalizerHelper Helper(*MF, Info, Observer, B); 251 B.setInstr(*MIBCTPOP); 252 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 253 Helper.widenScalar(*MIBCTPOP, 1, s16)); 254 255 auto CheckStr = R"( 256 CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64) 257 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8) 258 CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]] 259 CHECK: [[COPY:%[0-9]+]]:_(s32) = G_ZEXT [[CTPOP]]:_(s16) 260 )"; 261 262 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 263 } 264 265 // CTTZ_ZERO_UNDEF expansion in terms of CTTZ 266 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ3) { 267 setUp(); 268 if (!TM) 269 return; 270 271 // Declare your legalization info 272 DefineLegalizerInfo(A, { 273 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s64, s64}}); 274 }); 275 // Build 276 auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, 277 {LLT::scalar(64)}, {Copies[0]}); 278 AInfo Info(MF->getSubtarget()); 279 DummyGISelObserver Observer; 280 LegalizerHelper Helper(*MF, Info, Observer, B); 281 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == 282 LegalizerHelper::LegalizeResult::Legalized); 283 284 auto CheckStr = R"( 285 CHECK: CTTZ 286 )"; 287 288 // Check 289 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 290 } 291 292 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF 293 TEST_F(AArch64GISelMITest, LowerBitCountingCTLZ0) { 294 setUp(); 295 if (!TM) 296 return; 297 298 // Declare your legalization info 299 DefineLegalizerInfo(A, { 300 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s64, s64}}); 301 }); 302 // Build 303 auto MIBCTLZ = 304 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]}); 305 AInfo Info(MF->getSubtarget()); 306 DummyGISelObserver Observer; 307 LegalizerHelper Helper(*MF, Info, Observer, B); 308 EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) == 309 LegalizerHelper::LegalizeResult::Legalized); 310 311 auto CheckStr = R"( 312 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0 313 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 314 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]] 315 CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64 316 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]] 317 )"; 318 319 // Check 320 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 321 } 322 323 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall 324 TEST_F(AArch64GISelMITest, LowerBitCountingCTLZLibcall) { 325 setUp(); 326 if (!TM) 327 return; 328 329 // Declare your legalization info 330 DefineLegalizerInfo(A, { 331 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({{s32, s64}}); 332 }); 333 // Build 334 auto MIBCTLZ = 335 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(32)}, {Copies[0]}); 336 AInfo Info(MF->getSubtarget()); 337 DummyGISelObserver Observer; 338 LegalizerHelper Helper(*MF, Info, Observer, B); 339 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 340 Helper.lower(*MIBCTLZ, 0, LLT::scalar(32))); 341 342 auto CheckStr = R"( 343 CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF %0 344 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 345 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]] 346 CHECK: [[THIRTY2:%[0-9]+]]:_(s32) = G_CONSTANT i32 64 347 CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[THIRTY2]]:_, [[CZU]] 348 )"; 349 350 // Check 351 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 352 } 353 354 // CTLZ expansion 355 TEST_F(AArch64GISelMITest, LowerBitCountingCTLZ1) { 356 setUp(); 357 if (!TM) 358 return; 359 360 // Declare your legalization info 361 DefineLegalizerInfo(A, { 362 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s8, s8}}); 363 }); 364 // Build 365 // Trunc it to s8. 366 LLT s8{LLT::scalar(8)}; 367 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 368 auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc}); 369 AInfo Info(MF->getSubtarget()); 370 DummyGISelObserver Observer; 371 LegalizerHelper Helper(*MF, Info, Observer, B); 372 EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) == 373 LegalizerHelper::LegalizeResult::Legalized); 374 375 auto CheckStr = R"( 376 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 377 CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1 378 CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_ 379 CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_ 380 CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2 381 CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_ 382 CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_ 383 CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4 384 CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_ 385 CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_ 386 CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_ 387 CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8 388 CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_ 389 )"; 390 391 // Check 392 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 393 } 394 395 // CTLZ widening. 396 TEST_F(AArch64GISelMITest, WidenBitCountingCTLZ) { 397 setUp(); 398 if (!TM) 399 return; 400 401 // Declare your legalization info 402 DefineLegalizerInfo(A, { 403 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s16, s16}}); 404 }); 405 // Build 406 // Trunc it to s8. 407 LLT s8{LLT::scalar(8)}; 408 LLT s16{LLT::scalar(16)}; 409 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 410 auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc}); 411 AInfo Info(MF->getSubtarget()); 412 DummyGISelObserver Observer; 413 LegalizerHelper Helper(*MF, Info, Observer, B); 414 EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ, 1, s16) == 415 LegalizerHelper::LegalizeResult::Legalized); 416 417 auto CheckStr = R"( 418 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 419 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 420 CHECK: [[Ctlz:%[0-9]+]]:_(s16) = G_CTLZ [[Zext]] 421 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8 422 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[Ctlz]]:_, [[Cst8]]:_ 423 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]] 424 )"; 425 426 // Check 427 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 428 } 429 430 // CTLZ_ZERO_UNDEF widening. 431 TEST_F(AArch64GISelMITest, WidenBitCountingCTLZZeroUndef) { 432 setUp(); 433 if (!TM) 434 return; 435 436 // Declare your legalization info 437 DefineLegalizerInfo(A, { 438 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s16, s16}}); 439 }); 440 // Build 441 // Trunc it to s8. 442 LLT s8{LLT::scalar(8)}; 443 LLT s16{LLT::scalar(16)}; 444 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 445 auto MIBCTLZ_ZU = 446 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {s8}, {MIBTrunc}); 447 AInfo Info(MF->getSubtarget()); 448 DummyGISelObserver Observer; 449 LegalizerHelper Helper(*MF, Info, Observer, B); 450 EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 1, s16) == 451 LegalizerHelper::LegalizeResult::Legalized); 452 453 auto CheckStr = R"( 454 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 455 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 456 CHECK: [[CtlzZu:%[0-9]+]]:_(s16) = G_CTLZ_ZERO_UNDEF [[Zext]] 457 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8 458 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[CtlzZu]]:_, [[Cst8]]:_ 459 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]] 460 )"; 461 462 // Check 463 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 464 } 465 466 // CTPOP widening. 467 TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP) { 468 setUp(); 469 if (!TM) 470 return; 471 472 // Declare your legalization info 473 DefineLegalizerInfo(A, { 474 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}}); 475 }); 476 // Build 477 // Trunc it to s8. 478 LLT s8{LLT::scalar(8)}; 479 LLT s16{LLT::scalar(16)}; 480 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 481 auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s8}, {MIBTrunc}); 482 AInfo Info(MF->getSubtarget()); 483 DummyGISelObserver Observer; 484 LegalizerHelper Helper(*MF, Info, Observer, B); 485 EXPECT_TRUE(Helper.widenScalar(*MIBCTPOP, 1, s16) == 486 LegalizerHelper::LegalizeResult::Legalized); 487 488 auto CheckStr = R"( 489 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 490 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 491 CHECK: [[Ctpop:%[0-9]+]]:_(s16) = G_CTPOP [[Zext]] 492 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Ctpop]] 493 )"; 494 495 // Check 496 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 497 } 498 499 // CTTZ_ZERO_UNDEF widening. 500 TEST_F(AArch64GISelMITest, WidenBitCountingCTTZ_ZERO_UNDEF) { 501 setUp(); 502 if (!TM) 503 return; 504 505 // Declare your legalization info 506 DefineLegalizerInfo(A, { 507 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s16, s16}}); 508 }); 509 // Build 510 // Trunc it to s8. 511 LLT s8{LLT::scalar(8)}; 512 LLT s16{LLT::scalar(16)}; 513 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 514 auto MIBCTTZ_ZERO_UNDEF = 515 B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {s8}, {MIBTrunc}); 516 AInfo Info(MF->getSubtarget()); 517 DummyGISelObserver Observer; 518 LegalizerHelper Helper(*MF, Info, Observer, B); 519 EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 1, s16) == 520 LegalizerHelper::LegalizeResult::Legalized); 521 522 auto CheckStr = R"( 523 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 524 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 525 CHECK: [[CttzZu:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[Zext]] 526 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CttzZu]] 527 )"; 528 529 // Check 530 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 531 } 532 533 // CTTZ widening. 534 TEST_F(AArch64GISelMITest, WidenBitCountingCTTZ) { 535 setUp(); 536 if (!TM) 537 return; 538 539 // Declare your legalization info 540 DefineLegalizerInfo(A, { 541 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s16, s16}}); 542 }); 543 // Build 544 // Trunc it to s8. 545 LLT s8{LLT::scalar(8)}; 546 LLT s16{LLT::scalar(16)}; 547 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 548 auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, {s8}, {MIBTrunc}); 549 AInfo Info(MF->getSubtarget()); 550 DummyGISelObserver Observer; 551 LegalizerHelper Helper(*MF, Info, Observer, B); 552 EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ, 1, s16) == 553 LegalizerHelper::LegalizeResult::Legalized); 554 555 auto CheckStr = R"( 556 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 557 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 558 CHECK: [[Cst:%[0-9]+]]:_(s16) = G_CONSTANT i16 256 559 CHECK: [[Or:%[0-9]+]]:_(s16) = G_OR [[Zext]]:_, [[Cst]] 560 CHECK: [[Cttz:%[0-9]+]]:_(s16) = G_CTTZ [[Or]] 561 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Cttz]] 562 )"; 563 564 // Check 565 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 566 } 567 // UADDO widening. 568 TEST_F(AArch64GISelMITest, WidenUADDO) { 569 setUp(); 570 if (!TM) 571 return; 572 573 // Declare your legalization info 574 DefineLegalizerInfo(A, { 575 getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}}); 576 }); 577 // Build 578 // Trunc it to s8. 579 LLT s8{LLT::scalar(8)}; 580 LLT s16{LLT::scalar(16)}; 581 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 582 unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 583 auto MIBUAddO = 584 B.buildInstr(TargetOpcode::G_UADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc}); 585 AInfo Info(MF->getSubtarget()); 586 DummyGISelObserver Observer; 587 LegalizerHelper Helper(*MF, Info, Observer, B); 588 EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) == 589 LegalizerHelper::LegalizeResult::Legalized); 590 591 auto CheckStr = R"( 592 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 593 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 594 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 595 CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_ 596 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]] 597 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]] 598 CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[ZEXT]]:_ 599 CHECK: G_TRUNC [[ADD]] 600 )"; 601 602 // Check 603 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 604 } 605 606 // USUBO widening. 607 TEST_F(AArch64GISelMITest, WidenUSUBO) { 608 setUp(); 609 if (!TM) 610 return; 611 612 // Declare your legalization info 613 DefineLegalizerInfo(A, { 614 getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}}); 615 }); 616 // Build 617 // Trunc it to s8. 618 LLT s8{LLT::scalar(8)}; 619 LLT s16{LLT::scalar(16)}; 620 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 621 unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 622 auto MIBUSUBO = 623 B.buildInstr(TargetOpcode::G_USUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc}); 624 AInfo Info(MF->getSubtarget()); 625 DummyGISelObserver Observer; 626 LegalizerHelper Helper(*MF, Info, Observer, B); 627 EXPECT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) == 628 LegalizerHelper::LegalizeResult::Legalized); 629 630 auto CheckStr = R"( 631 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 632 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 633 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 634 CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_ 635 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]] 636 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]] 637 CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[ZEXT]]:_ 638 CHECK: G_TRUNC [[SUB]] 639 )"; 640 641 // Check 642 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 643 } 644 645 // SADDO widening. 646 TEST_F(AArch64GISelMITest, WidenSADDO) { 647 setUp(); 648 if (!TM) 649 return; 650 651 // Declare your legalization info 652 DefineLegalizerInfo(A, { 653 getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}}); 654 }); 655 // Build 656 // Trunc it to s8. 657 LLT s8{LLT::scalar(8)}; 658 LLT s16{LLT::scalar(16)}; 659 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 660 unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 661 auto MIBSAddO = 662 B.buildInstr(TargetOpcode::G_SADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc}); 663 AInfo Info(MF->getSubtarget()); 664 DummyGISelObserver Observer; 665 LegalizerHelper Helper(*MF, Info, Observer, B); 666 EXPECT_TRUE(Helper.widenScalar(*MIBSAddO, 0, s16) == 667 LegalizerHelper::LegalizeResult::Legalized); 668 669 auto CheckStr = R"( 670 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 671 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]] 672 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]] 673 CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_ 674 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]] 675 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]] 676 CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[SEXT]]:_ 677 CHECK: G_TRUNC [[ADD]] 678 )"; 679 680 // Check 681 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 682 } 683 684 // SSUBO widening. 685 TEST_F(AArch64GISelMITest, WidenSSUBO) { 686 setUp(); 687 if (!TM) 688 return; 689 690 // Declare your legalization info 691 DefineLegalizerInfo(A, { 692 getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}}); 693 }); 694 // Build 695 // Trunc it to s8. 696 LLT s8{LLT::scalar(8)}; 697 LLT s16{LLT::scalar(16)}; 698 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 699 unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 700 auto MIBSSUBO = 701 B.buildInstr(TargetOpcode::G_SSUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc}); 702 AInfo Info(MF->getSubtarget()); 703 DummyGISelObserver Observer; 704 LegalizerHelper Helper(*MF, Info, Observer, B); 705 EXPECT_TRUE(Helper.widenScalar(*MIBSSUBO, 0, s16) == 706 LegalizerHelper::LegalizeResult::Legalized); 707 708 auto CheckStr = R"( 709 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 710 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]] 711 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]] 712 CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_ 713 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]] 714 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]] 715 CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[SEXT]]:_ 716 CHECK: G_TRUNC [[SUB]] 717 )"; 718 719 // Check 720 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 721 } 722 723 TEST_F(AArch64GISelMITest, WidenUADDE) { 724 setUp(); 725 if (!TM) 726 return; 727 728 // Declare your legalization info 729 DefineLegalizerInfo(A, { 730 getActionDefinitionsBuilder(G_UADDE).legalFor({{s16, s16}}); 731 }); 732 // Build 733 // Trunc it to s8. 734 LLT s8{LLT::scalar(8)}; 735 LLT s16{LLT::scalar(16)}; 736 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 737 auto CarryIn = B.buildUndef(LLT::scalar(1)); 738 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 739 auto MIBUAddO = B.buildInstr(TargetOpcode::G_UADDE, {s8, CarryReg}, 740 {MIBTrunc, MIBTrunc, CarryIn}); 741 AInfo Info(MF->getSubtarget()); 742 DummyGISelObserver Observer; 743 LegalizerHelper Helper(*MF, Info, Observer, B); 744 EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) == 745 LegalizerHelper::LegalizeResult::Legalized); 746 747 const char *CheckStr = R"( 748 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 749 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF 750 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 751 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 752 CHECK: [[UADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_ 753 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[UADDE]] 754 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]] 755 CHECK: G_ICMP intpred(ne), [[UADDE]]:_(s16), [[ZEXT]]:_ 756 CHECK: G_TRUNC [[UADDE]] 757 )"; 758 759 // Check 760 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 761 } 762 763 TEST_F(AArch64GISelMITest, WidenUSUBE) { 764 setUp(); 765 if (!TM) 766 return; 767 768 // Declare your legalization info 769 DefineLegalizerInfo(A, { 770 getActionDefinitionsBuilder(G_USUBE).legalFor({{s16, s16}}); 771 }); 772 // Build 773 // Trunc it to s8. 774 LLT s8{LLT::scalar(8)}; 775 LLT s16{LLT::scalar(16)}; 776 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 777 auto CarryIn = B.buildUndef(LLT::scalar(1)); 778 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 779 auto MIBUSUBE = B.buildInstr(TargetOpcode::G_USUBE, {s8, CarryReg}, 780 {MIBTrunc, MIBTrunc, CarryIn}); 781 AInfo Info(MF->getSubtarget()); 782 DummyGISelObserver Observer; 783 LegalizerHelper Helper(*MF, Info, Observer, B); 784 EXPECT_TRUE(Helper.widenScalar(*MIBUSUBE, 0, s16) == 785 LegalizerHelper::LegalizeResult::Legalized); 786 787 const char *CheckStr = R"( 788 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 789 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF 790 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 791 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 792 CHECK: [[USUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_ 793 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[USUBE]] 794 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]] 795 CHECK: G_ICMP intpred(ne), [[USUBE]]:_(s16), [[ZEXT]]:_ 796 CHECK: G_TRUNC [[USUBE]] 797 )"; 798 799 // Check 800 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 801 } 802 803 TEST_F(AArch64GISelMITest, WidenSADDE) { 804 setUp(); 805 if (!TM) 806 return; 807 808 // Declare your legalization info 809 DefineLegalizerInfo(A, { 810 getActionDefinitionsBuilder({G_SADDE, G_UADDE}).legalFor({{s16, s16}}); 811 }); 812 // Build 813 // Trunc it to s8. 814 LLT s8{LLT::scalar(8)}; 815 LLT s16{LLT::scalar(16)}; 816 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 817 auto CarryIn = B.buildUndef(LLT::scalar(1)); 818 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 819 auto MIBUAddO = B.buildInstr(TargetOpcode::G_SADDE, {s8, CarryReg}, 820 {MIBTrunc, MIBTrunc, CarryIn}); 821 AInfo Info(MF->getSubtarget()); 822 DummyGISelObserver Observer; 823 LegalizerHelper Helper(*MF, Info, Observer, B); 824 EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) == 825 LegalizerHelper::LegalizeResult::Legalized); 826 827 const char *CheckStr = R"( 828 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 829 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF 830 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]] 831 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]] 832 CHECK: [[SADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_ 833 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SADDE]] 834 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]] 835 CHECK: G_ICMP intpred(ne), [[SADDE]]:_(s16), [[SEXT]]:_ 836 CHECK: G_TRUNC [[SADDE]] 837 )"; 838 839 // Check 840 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 841 } 842 843 TEST_F(AArch64GISelMITest, WidenSSUBE) { 844 setUp(); 845 if (!TM) 846 return; 847 848 // Declare your legalization info 849 DefineLegalizerInfo(A, { 850 getActionDefinitionsBuilder({G_SSUBE, G_USUBE}).legalFor({{s16, s16}}); 851 }); 852 // Build 853 // Trunc it to s8. 854 LLT s8{LLT::scalar(8)}; 855 LLT s16{LLT::scalar(16)}; 856 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 857 auto CarryIn = B.buildUndef(LLT::scalar(1)); 858 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 859 auto MIBSSUBE = B.buildInstr(TargetOpcode::G_SSUBE, {s8, CarryReg}, 860 {MIBTrunc, MIBTrunc, CarryIn}); 861 AInfo Info(MF->getSubtarget()); 862 DummyGISelObserver Observer; 863 LegalizerHelper Helper(*MF, Info, Observer, B); 864 EXPECT_TRUE(Helper.widenScalar(*MIBSSUBE, 0, s16) == 865 LegalizerHelper::LegalizeResult::Legalized); 866 867 const char *CheckStr = R"( 868 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 869 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF 870 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]] 871 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]] 872 CHECK: [[SSUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_ 873 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SSUBE]] 874 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]] 875 CHECK: G_ICMP intpred(ne), [[SSUBE]]:_(s16), [[SEXT]]:_ 876 CHECK: G_TRUNC [[SSUBE]] 877 )"; 878 879 // Check 880 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 881 } 882 883 TEST_F(AArch64GISelMITest, NarrowUADDO) { 884 setUp(); 885 if (!TM) 886 return; 887 888 LLT S1 = LLT::scalar(1); 889 LLT S32 = LLT::scalar(32); 890 LLT S96 = LLT::scalar(96); 891 DefineLegalizerInfo(A, { 892 getActionDefinitionsBuilder({G_UADDO, G_UADDE}) 893 .legalFor({{LLT::scalar(32), LLT::scalar(1)}}); 894 }); 895 896 auto Op0 = B.buildUndef(S96); 897 auto Op1 = B.buildUndef(S96); 898 auto UADDO = B.buildUAddo(S96, S1, Op0, Op1); 899 900 AInfo Info(MF->getSubtarget()); 901 DummyGISelObserver Observer; 902 LegalizerHelper Helper(*MF, Info, Observer, B); 903 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 904 Helper.narrowScalar(*UADDO, 0, S32)); 905 906 const char *CheckStr = R"( 907 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 908 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 909 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]] 910 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]] 911 CHECK: [[UADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_ 912 CHECK: [[UADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_ 913 CHECK: [[UADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_ 914 CHECK: [[UADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDO0]]:_(s32), [[UADDO1]]:_(s32), [[UADDO2]]:_(s32) 915 )"; 916 917 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 918 } 919 920 TEST_F(AArch64GISelMITest, NarrowUSUBO) { 921 setUp(); 922 if (!TM) 923 return; 924 925 LLT S1 = LLT::scalar(1); 926 LLT S32 = LLT::scalar(32); 927 LLT S96 = LLT::scalar(96); 928 DefineLegalizerInfo(A, { 929 getActionDefinitionsBuilder({G_USUBO, G_USUBE}) 930 .legalFor({{LLT::scalar(32), LLT::scalar(1)}}); 931 }); 932 933 auto Op0 = B.buildUndef(S96); 934 auto Op1 = B.buildUndef(S96); 935 auto USUBO = B.buildUSubo(S96, S1, Op0, Op1); 936 937 AInfo Info(MF->getSubtarget()); 938 DummyGISelObserver Observer; 939 LegalizerHelper Helper(*MF, Info, Observer, B); 940 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 941 Helper.narrowScalar(*USUBO, 0, S32)); 942 943 const char *CheckStr = R"( 944 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 945 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 946 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]] 947 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]] 948 CHECK: [[USUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_ 949 CHECK: [[USUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_ 950 CHECK: [[USUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_ 951 CHECK: [[USUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBO0]]:_(s32), [[USUBO1]]:_(s32), [[USUBO2]]:_(s32) 952 )"; 953 954 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 955 } 956 957 TEST_F(AArch64GISelMITest, NarrowSADDO) { 958 setUp(); 959 if (!TM) 960 return; 961 962 LLT S1 = LLT::scalar(1); 963 LLT S32 = LLT::scalar(32); 964 LLT S96 = LLT::scalar(96); 965 DefineLegalizerInfo(A, { 966 getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_SADDE}) 967 .legalFor({{LLT::scalar(32), LLT::scalar(1)}}); 968 }); 969 970 auto Op0 = B.buildUndef(S96); 971 auto Op1 = B.buildUndef(S96); 972 auto SADDO = B.buildSAddo(S96, S1, Op0, Op1); 973 974 AInfo Info(MF->getSubtarget()); 975 DummyGISelObserver Observer; 976 LegalizerHelper Helper(*MF, Info, Observer, B); 977 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 978 Helper.narrowScalar(*SADDO, 0, S32)); 979 980 const char *CheckStr = R"( 981 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 982 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 983 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]] 984 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]] 985 CHECK: [[SADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_ 986 CHECK: [[SADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_ 987 CHECK: [[SADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_ 988 CHECK: [[SADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDO0]]:_(s32), [[SADDO1]]:_(s32), [[SADDO2]]:_(s32) 989 )"; 990 991 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 992 } 993 994 TEST_F(AArch64GISelMITest, NarrowSSUBO) { 995 setUp(); 996 if (!TM) 997 return; 998 999 LLT S1 = LLT::scalar(1); 1000 LLT S32 = LLT::scalar(32); 1001 LLT S96 = LLT::scalar(96); 1002 DefineLegalizerInfo(A, { 1003 getActionDefinitionsBuilder({G_USUBO, G_USUBE, G_SSUBE}) 1004 .legalFor({{LLT::scalar(32), LLT::scalar(1)}}); 1005 }); 1006 1007 auto Op0 = B.buildUndef(S96); 1008 auto Op1 = B.buildUndef(S96); 1009 auto SSUBO = B.buildSSubo(S96, S1, Op0, Op1); 1010 1011 AInfo Info(MF->getSubtarget()); 1012 DummyGISelObserver Observer; 1013 LegalizerHelper Helper(*MF, Info, Observer, B); 1014 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1015 Helper.narrowScalar(*SSUBO, 0, S32)); 1016 1017 const char *CheckStr = R"( 1018 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1019 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1020 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]] 1021 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]] 1022 CHECK: [[SSUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_ 1023 CHECK: [[SSUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_ 1024 CHECK: [[SSUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_ 1025 CHECK: [[SSUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBO0]]:_(s32), [[SSUBO1]]:_(s32), [[SSUBO2]]:_(s32) 1026 )"; 1027 1028 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1029 } 1030 1031 TEST_F(AArch64GISelMITest, NarrowUADDE) { 1032 setUp(); 1033 if (!TM) 1034 return; 1035 1036 LLT S1 = LLT::scalar(1); 1037 LLT S32 = LLT::scalar(32); 1038 LLT S96 = LLT::scalar(96); 1039 DefineLegalizerInfo(A, { 1040 getActionDefinitionsBuilder(G_UADDE).legalFor( 1041 {{LLT::scalar(32), LLT::scalar(1)}}); 1042 }); 1043 1044 auto Op0 = B.buildUndef(S96); 1045 auto Op1 = B.buildUndef(S96); 1046 auto Op2 = B.buildUndef(S1); 1047 auto UADDE = B.buildUAdde(S96, S1, Op0, Op1, Op2); 1048 1049 AInfo Info(MF->getSubtarget()); 1050 DummyGISelObserver Observer; 1051 LegalizerHelper Helper(*MF, Info, Observer, B); 1052 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1053 Helper.narrowScalar(*UADDE, 0, S32)); 1054 1055 const char *CheckStr = R"( 1056 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1057 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1058 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF 1059 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]] 1060 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]] 1061 CHECK: [[UADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_ 1062 CHECK: [[UADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_ 1063 CHECK: [[UADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_ 1064 CHECK: [[UADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDE0]]:_(s32), [[UADDE1]]:_(s32), [[UADDE2]]:_(s32) 1065 )"; 1066 1067 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1068 } 1069 1070 TEST_F(AArch64GISelMITest, NarrowUSUBE) { 1071 setUp(); 1072 if (!TM) 1073 return; 1074 1075 LLT S1 = LLT::scalar(1); 1076 LLT S32 = LLT::scalar(32); 1077 LLT S96 = LLT::scalar(96); 1078 DefineLegalizerInfo(A, { 1079 getActionDefinitionsBuilder(G_USUBE).legalFor( 1080 {{LLT::scalar(32), LLT::scalar(1)}}); 1081 }); 1082 1083 auto Op0 = B.buildUndef(S96); 1084 auto Op1 = B.buildUndef(S96); 1085 auto Op2 = B.buildUndef(S1); 1086 auto USUBE = B.buildUSube(S96, S1, Op0, Op1, Op2); 1087 1088 AInfo Info(MF->getSubtarget()); 1089 DummyGISelObserver Observer; 1090 LegalizerHelper Helper(*MF, Info, Observer, B); 1091 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1092 Helper.narrowScalar(*USUBE, 0, S32)); 1093 1094 const char *CheckStr = R"( 1095 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1096 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1097 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF 1098 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]] 1099 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]] 1100 CHECK: [[USUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_ 1101 CHECK: [[USUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_ 1102 CHECK: [[USUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_ 1103 CHECK: [[USUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBE0]]:_(s32), [[USUBE1]]:_(s32), [[USUBE2]]:_(s32) 1104 )"; 1105 1106 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1107 } 1108 1109 TEST_F(AArch64GISelMITest, NarrowSADDE) { 1110 setUp(); 1111 if (!TM) 1112 return; 1113 1114 LLT S1 = LLT::scalar(1); 1115 LLT S32 = LLT::scalar(32); 1116 LLT S96 = LLT::scalar(96); 1117 DefineLegalizerInfo(A, { 1118 getActionDefinitionsBuilder({G_SADDE, G_UADDE}) 1119 .legalFor({{LLT::scalar(32), LLT::scalar(1)}}); 1120 }); 1121 1122 auto Op0 = B.buildUndef(S96); 1123 auto Op1 = B.buildUndef(S96); 1124 auto Op2 = B.buildUndef(S1); 1125 auto SADDE = B.buildSAdde(S96, S1, Op0, Op1, Op2); 1126 1127 AInfo Info(MF->getSubtarget()); 1128 DummyGISelObserver Observer; 1129 LegalizerHelper Helper(*MF, Info, Observer, B); 1130 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1131 Helper.narrowScalar(*SADDE, 0, S32)); 1132 1133 const char *CheckStr = R"( 1134 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1135 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1136 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF 1137 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]] 1138 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]] 1139 CHECK: [[SADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_ 1140 CHECK: [[SADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_ 1141 CHECK: [[SADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_ 1142 CHECK: [[SADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDE0]]:_(s32), [[SADDE1]]:_(s32), [[SADDE2]]:_(s32) 1143 )"; 1144 1145 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1146 } 1147 1148 TEST_F(AArch64GISelMITest, NarrowSSUBE) { 1149 setUp(); 1150 if (!TM) 1151 return; 1152 1153 LLT S1 = LLT::scalar(1); 1154 LLT S32 = LLT::scalar(32); 1155 LLT S96 = LLT::scalar(96); 1156 DefineLegalizerInfo(A, { 1157 getActionDefinitionsBuilder({G_SSUBE, G_USUBE}) 1158 .legalFor({{LLT::scalar(32), LLT::scalar(1)}}); 1159 }); 1160 1161 auto Op0 = B.buildUndef(S96); 1162 auto Op1 = B.buildUndef(S96); 1163 auto Op2 = B.buildUndef(S1); 1164 auto SSUBE = B.buildSSube(S96, S1, Op0, Op1, Op2); 1165 1166 AInfo Info(MF->getSubtarget()); 1167 DummyGISelObserver Observer; 1168 LegalizerHelper Helper(*MF, Info, Observer, B); 1169 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1170 Helper.narrowScalar(*SSUBE, 0, S32)); 1171 1172 const char *CheckStr = R"( 1173 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1174 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 1175 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF 1176 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]] 1177 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]] 1178 CHECK: [[SSUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_ 1179 CHECK: [[SSUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_ 1180 CHECK: [[SSUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_ 1181 CHECK: [[SSUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBE0]]:_(s32), [[SSUBE1]]:_(s32), [[SSUBE2]]:_(s32) 1182 )"; 1183 1184 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1185 } 1186 1187 TEST_F(AArch64GISelMITest, FewerElementsAnd) { 1188 setUp(); 1189 if (!TM) 1190 return; 1191 1192 const LLT V2S32 = LLT::vector(2, 32); 1193 const LLT V5S32 = LLT::vector(5, 32); 1194 1195 // Declare your legalization info 1196 DefineLegalizerInfo(A, { 1197 getActionDefinitionsBuilder(G_AND) 1198 .legalFor({s32}); 1199 }); 1200 1201 auto Op0 = B.buildUndef(V5S32); 1202 auto Op1 = B.buildUndef(V5S32); 1203 auto And = B.buildAnd(V5S32, Op0, Op1); 1204 1205 AInfo Info(MF->getSubtarget()); 1206 DummyGISelObserver Observer; 1207 LegalizerHelper Helper(*MF, Info, Observer, B); 1208 B.setInstr(*And); 1209 EXPECT_TRUE(Helper.fewerElementsVector(*And, 0, V2S32) == 1210 LegalizerHelper::LegalizeResult::Legalized); 1211 1212 auto CheckStr = R"( 1213 CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF 1214 CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF 1215 CHECK: [[VALUE0:%[0-9]+]]:_(s32), [[VALUE1:%[0-9]+]]:_(s32), [[VALUE2:%[0-9]+]]:_(s32), [[VALUE3:%[0-9]+]]:_(s32), [[VALUE4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]:_(<5 x s32>) 1216 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 1217 CHECK: [[VECTOR0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE0]]:_(s32), [[VALUE1]]:_(s32) 1218 CHECK: [[VECTOR1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE2]]:_(s32), [[VALUE3]]:_(s32) 1219 CHECK: [[VECTOR2:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE4]]:_(s32), [[IMP_DEF2]]:_(s32) 1220 CHECK: [[IMP_DEF3:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 1221 CHECK: [[VALUE5:%[0-9]+]]:_(s32), [[VALUE6:%[0-9]+]]:_(s32), [[VALUE7:%[0-9]+]]:_(s32), [[VALUE8:%[0-9]+]]:_(s32), [[VALUE9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]:_(<5 x s32>) 1222 CHECK: [[IMP_DEF4:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 1223 CHECK: [[VECTOR3:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE5]]:_(s32), [[VALUE6]]:_(s32) 1224 CHECK: [[VECTOR4:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE7]]:_(s32), [[VALUE8]]:_(s32) 1225 CHECK: [[VECTOR5:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE9]]:_(s32), [[IMP_DEF4]]:_(s32) 1226 CHECK: [[IMP_DEF5:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 1227 1228 CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR0]]:_, [[VECTOR3]]:_ 1229 CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR1]]:_, [[VECTOR4]]:_ 1230 CHECK: [[AND2:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR2]]:_, [[VECTOR5]]:_ 1231 CHECK: [[IMP_DEF6:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 1232 1233 CHECK: [[VECTOR6:%[0-9]+]]:_(<10 x s32>) = G_CONCAT_VECTORS [[AND0]]:_(<2 x s32>), [[AND1]]:_(<2 x s32>), [[AND2]]:_(<2 x s32>), [[IMP_DEF6]]:_(<2 x s32>), [[IMP_DEF6]]:_(<2 x s32>) 1234 CHECK: [[VECTOR7:%[0-9]+]]:_(<10 x s32>) = G_CONCAT_VECTORS [[AND0]]:_(<2 x s32>), [[AND1]]:_(<2 x s32>), [[AND2]]:_(<2 x s32>), [[IMP_DEF6]]:_(<2 x s32>), [[IMP_DEF6]]:_(<2 x s32>) 1235 CHECK: [[VECTOR8:%[0-9]+]]:_(<5 x s32>), [[VECTOR9:%[0-9]+]]:_(<5 x s32>) = G_UNMERGE_VALUES [[VECTOR7]]:_(<10 x s32>) 1236 )"; 1237 1238 // Check 1239 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1240 } 1241 1242 TEST_F(AArch64GISelMITest, MoreElementsAnd) { 1243 setUp(); 1244 if (!TM) 1245 return; 1246 1247 LLT s32 = LLT::scalar(32); 1248 LLT v2s32 = LLT::vector(2, 32); 1249 LLT v6s32 = LLT::vector(6, 32); 1250 1251 LegalizerInfo LI; 1252 LI.getActionDefinitionsBuilder(TargetOpcode::G_AND) 1253 .legalFor({v6s32}) 1254 .clampMinNumElements(0, s32, 6); 1255 LI.computeTables(); 1256 1257 DummyGISelObserver Observer; 1258 LegalizerHelper Helper(*MF, LI, Observer, B); 1259 1260 B.setInsertPt(*EntryMBB, EntryMBB->end()); 1261 1262 auto Val0 = B.buildBitcast(v2s32, Copies[0]); 1263 auto Val1 = B.buildBitcast(v2s32, Copies[1]); 1264 1265 auto And = B.buildAnd(v2s32, Val0, Val1); 1266 1267 B.setInstr(*And); 1268 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1269 Helper.moreElementsVector(*And, 0, v6s32)); 1270 1271 auto CheckStr = R"( 1272 CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST 1273 CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST 1274 CHECK: [[IMP_DEF0:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 1275 CHECK: [[CONCAT0:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>) 1276 CHECK: [[IMP_DEF1:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 1277 CHECK: [[CONCAT1:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>) 1278 CHECK: [[AND:%[0-9]+]]:_(<6 x s32>) = G_AND [[CONCAT0]]:_, [[CONCAT1]]:_ 1279 CHECK: (<2 x s32>) = G_UNMERGE_VALUES [[AND]]:_(<6 x s32>) 1280 )"; 1281 1282 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1283 } 1284 1285 TEST_F(AArch64GISelMITest, FewerElementsPhi) { 1286 setUp(); 1287 if (!TM) 1288 return; 1289 1290 LLT s1 = LLT::scalar(1); 1291 LLT s32 = LLT::scalar(32); 1292 LLT s64 = LLT::scalar(64); 1293 LLT v2s32 = LLT::vector(2, 32); 1294 LLT v5s32 = LLT::vector(5, 32); 1295 1296 LegalizerInfo LI; 1297 LI.getActionDefinitionsBuilder(TargetOpcode::G_PHI) 1298 .legalFor({v2s32}) 1299 .clampMinNumElements(0, s32, 2); 1300 LI.computeTables(); 1301 1302 LLT PhiTy = v5s32; 1303 DummyGISelObserver Observer; 1304 LegalizerHelper Helper(*MF, LI, Observer, B); 1305 B.setMBB(*EntryMBB); 1306 1307 MachineBasicBlock *MidMBB = MF->CreateMachineBasicBlock(); 1308 MachineBasicBlock *EndMBB = MF->CreateMachineBasicBlock(); 1309 MF->insert(MF->end(), MidMBB); 1310 MF->insert(MF->end(), EndMBB); 1311 1312 EntryMBB->addSuccessor(MidMBB); 1313 EntryMBB->addSuccessor(EndMBB); 1314 MidMBB->addSuccessor(EndMBB); 1315 1316 auto InitVal = B.buildUndef(PhiTy); 1317 auto InitOtherVal = B.buildConstant(s64, 999); 1318 1319 auto ICmp = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]); 1320 B.buildBrCond(ICmp.getReg(0), *MidMBB); 1321 B.buildBr(*EndMBB); 1322 1323 1324 B.setMBB(*MidMBB); 1325 auto MidVal = B.buildUndef(PhiTy); 1326 auto MidOtherVal = B.buildConstant(s64, 345); 1327 B.buildBr(*EndMBB); 1328 1329 B.setMBB(*EndMBB); 1330 auto Phi = B.buildInstr(TargetOpcode::G_PHI) 1331 .addDef(MRI->createGenericVirtualRegister(PhiTy)) 1332 .addUse(InitVal.getReg(0)) 1333 .addMBB(EntryMBB) 1334 .addUse(MidVal.getReg(0)) 1335 .addMBB(MidMBB); 1336 1337 // Insert another irrelevant phi to make sure the rebuild is inserted after 1338 // it. 1339 B.buildInstr(TargetOpcode::G_PHI) 1340 .addDef(MRI->createGenericVirtualRegister(s64)) 1341 .addUse(InitOtherVal.getReg(0)) 1342 .addMBB(EntryMBB) 1343 .addUse(MidOtherVal.getReg(0)) 1344 .addMBB(MidMBB); 1345 1346 // Add some use instruction after the phis. 1347 B.buildAnd(PhiTy, Phi.getReg(0), Phi.getReg(0)); 1348 1349 B.setInstr(*Phi); 1350 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1351 Helper.fewerElementsVector(*Phi, 0, v2s32)); 1352 1353 auto CheckStr = R"( 1354 CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF 1355 CHECK: [[EXTRACT0:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 0 1356 CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 64 1357 CHECK: [[EXTRACT2:%[0-9]+]]:_(s32) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 128 1358 CHECK: G_BRCOND 1359 1360 CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF 1361 CHECK: [[EXTRACT3:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 0 1362 CHECK: [[EXTRACT4:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 64 1363 CHECK: [[EXTRACT5:%[0-9]+]]:_(s32) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 128 1364 CHECK: G_BR 1365 1366 CHECK: [[PHI0:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT0]]:_(<2 x s32>), %bb.0, [[EXTRACT3]]:_(<2 x s32>), %bb.1 1367 CHECK: [[PHI1:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT1]]:_(<2 x s32>), %bb.0, [[EXTRACT4]]:_(<2 x s32>), %bb.1 1368 CHECK: [[PHI2:%[0-9]+]]:_(s32) = G_PHI [[EXTRACT2]]:_(s32), %bb.0, [[EXTRACT5]]:_(s32), %bb.1 1369 1370 CHECK: [[OTHER_PHI:%[0-9]+]]:_(s64) = G_PHI 1371 CHECK: [[REBUILD_VAL_IMPDEF:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF 1372 CHECK: [[INSERT0:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[REBUILD_VAL_IMPDEF]]:_, [[PHI0]]:_(<2 x s32>), 0 1373 CHECK: [[INSERT1:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT0]]:_, [[PHI1]]:_(<2 x s32>), 64 1374 CHECK: [[INSERT2:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT1]]:_, [[PHI2]]:_(s32), 128 1375 CHECK: [[USE_OP:%[0-9]+]]:_(<5 x s32>) = G_AND [[INSERT2]]:_, [[INSERT2]]:_ 1376 )"; 1377 1378 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1379 } 1380 1381 // FNEG expansion in terms of XOR 1382 TEST_F(AArch64GISelMITest, LowerFNEG) { 1383 setUp(); 1384 if (!TM) 1385 return; 1386 1387 // Declare your legalization info 1388 DefineLegalizerInfo(A, { 1389 getActionDefinitionsBuilder(G_FSUB).legalFor({s64}); 1390 }); 1391 1392 // Build Instr. Make sure FMF are preserved. 1393 auto FAdd = 1394 B.buildInstr(TargetOpcode::G_FADD, {LLT::scalar(64)}, {Copies[0], Copies[1]}, 1395 MachineInstr::MIFlag::FmNsz); 1396 1397 // Should not propagate the flags of src instruction. 1398 auto FNeg0 = 1399 B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {FAdd.getReg(0)}, 1400 {MachineInstr::MIFlag::FmArcp}); 1401 1402 // Preserve the one flag. 1403 auto FNeg1 = 1404 B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {Copies[0]}, 1405 MachineInstr::MIFlag::FmNoInfs); 1406 1407 AInfo Info(MF->getSubtarget()); 1408 DummyGISelObserver Observer; 1409 LegalizerHelper Helper(*MF, Info, Observer, B); 1410 // Perform Legalization 1411 B.setInstr(*FNeg0); 1412 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1413 Helper.lower(*FNeg0, 0, LLT::scalar(64))); 1414 B.setInstr(*FNeg1); 1415 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1416 Helper.lower(*FNeg1, 0, LLT::scalar(64))); 1417 1418 auto CheckStr = R"( 1419 CHECK: [[FADD:%[0-9]+]]:_(s64) = nsz G_FADD %0:_, %1:_ 1420 CHECK: [[CONST0:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808 1421 CHECK: [[FSUB0:%[0-9]+]]:_(s64) = G_XOR [[FADD]]:_, [[CONST0]]:_ 1422 CHECK: [[CONST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808 1423 CHECK: [[FSUB1:%[0-9]+]]:_(s64) = G_XOR %0:_, [[CONST1]]:_ 1424 )"; 1425 1426 // Check 1427 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1428 } 1429 1430 TEST_F(AArch64GISelMITest, LowerMinMax) { 1431 setUp(); 1432 if (!TM) 1433 return; 1434 1435 LLT s64 = LLT::scalar(64); 1436 LLT v2s32 = LLT::vector(2, 32); 1437 1438 DefineLegalizerInfo(A, { 1439 getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX}) 1440 .lowerFor({s64, LLT::vector(2, s32)}); 1441 }); 1442 1443 auto SMin = B.buildSMin(s64, Copies[0], Copies[1]); 1444 auto SMax = B.buildSMax(s64, Copies[0], Copies[1]); 1445 auto UMin = B.buildUMin(s64, Copies[0], Copies[1]); 1446 auto UMax = B.buildUMax(s64, Copies[0], Copies[1]); 1447 1448 auto VecVal0 = B.buildBitcast(v2s32, Copies[0]); 1449 auto VecVal1 = B.buildBitcast(v2s32, Copies[1]); 1450 1451 auto SMinV = B.buildSMin(v2s32, VecVal0, VecVal1); 1452 auto SMaxV = B.buildSMax(v2s32, VecVal0, VecVal1); 1453 auto UMinV = B.buildUMin(v2s32, VecVal0, VecVal1); 1454 auto UMaxV = B.buildUMax(v2s32, VecVal0, VecVal1); 1455 1456 AInfo Info(MF->getSubtarget()); 1457 DummyGISelObserver Observer; 1458 LegalizerHelper Helper(*MF, Info, Observer, B); 1459 B.setInstr(*SMin); 1460 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1461 Helper.lower(*SMin, 0, s64)); 1462 B.setInstr(*SMax); 1463 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1464 Helper.lower(*SMax, 0, s64)); 1465 B.setInstr(*UMin); 1466 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1467 Helper.lower(*UMin, 0, s64)); 1468 B.setInstr(*UMax); 1469 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1470 Helper.lower(*UMax, 0, s64)); 1471 1472 B.setInstr(*SMinV); 1473 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1474 Helper.lower(*SMinV, 0, v2s32)); 1475 B.setInstr(*SMaxV); 1476 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1477 Helper.lower(*SMaxV, 0, v2s32)); 1478 B.setInstr(*UMinV); 1479 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1480 Helper.lower(*UMinV, 0, v2s32)); 1481 B.setInstr(*UMaxV); 1482 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1483 Helper.lower(*UMaxV, 0, v2s32)); 1484 1485 auto CheckStr = R"( 1486 CHECK: [[CMP0:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), %0:_(s64), %1:_ 1487 CHECK: [[SMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP0]]:_(s1), %0:_, %1:_ 1488 1489 CHECK: [[CMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), %0:_(s64), %1:_ 1490 CHECK: [[SMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP1]]:_(s1), %0:_, %1:_ 1491 1492 CHECK: [[CMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), %0:_(s64), %1:_ 1493 CHECK: [[UMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP2]]:_(s1), %0:_, %1:_ 1494 1495 CHECK: [[CMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), %0:_(s64), %1:_ 1496 CHECK: [[UMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP3]]:_(s1), %0:_, %1:_ 1497 1498 CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %0:_(s64) 1499 CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %1:_(s64) 1500 1501 CHECK: [[VCMP0:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(slt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_ 1502 CHECK: [[SMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP0]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_ 1503 1504 CHECK: [[VCMP1:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(sgt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_ 1505 CHECK: [[SMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP1]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_ 1506 1507 CHECK: [[VCMP2:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_ 1508 CHECK: [[UMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP2]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_ 1509 1510 CHECK: [[VCMP3:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ugt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_ 1511 CHECK: [[UMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP3]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_ 1512 )"; 1513 1514 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1515 } 1516 1517 TEST_F(AArch64GISelMITest, WidenScalarBuildVector) { 1518 setUp(); 1519 if (!TM) 1520 return; 1521 1522 LLT S32 = LLT::scalar(32); 1523 LLT S16 = LLT::scalar(16); 1524 LLT V2S16 = LLT::vector(2, S16); 1525 LLT V2S32 = LLT::vector(2, S32); 1526 1527 DefineLegalizerInfo(A, { 1528 getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX}) 1529 .lowerFor({s64, LLT::vector(2, s32)}); 1530 }); 1531 1532 AInfo Info(MF->getSubtarget()); 1533 DummyGISelObserver Observer; 1534 LegalizerHelper Helper(*MF, Info, Observer, B); 1535 B.setInsertPt(*EntryMBB, EntryMBB->end()); 1536 1537 Register Constant0 = B.buildConstant(S16, 1).getReg(0); 1538 Register Constant1 = B.buildConstant(S16, 2).getReg(0); 1539 auto BV0 = B.buildBuildVector(V2S16, {Constant0, Constant1}); 1540 auto BV1 = B.buildBuildVector(V2S16, {Constant0, Constant1}); 1541 1542 B.setInstr(*BV0); 1543 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1544 Helper.widenScalar(*BV0, 0, V2S32)); 1545 B.setInstr(*BV1); 1546 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1547 Helper.widenScalar(*BV1, 1, S32)); 1548 1549 auto CheckStr = R"( 1550 CHECK: [[K0:%[0-9]+]]:_(s16) = G_CONSTANT i16 1 1551 CHECK-NEXT: [[K1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2 1552 CHECK-NEXT: [[EXT_K0_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]] 1553 CHECK-NEXT: [[EXT_K1_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]] 1554 CHECK-NEXT: [[BV0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[EXT_K0_0]]:_(s32), [[EXT_K1_0]]:_(s32) 1555 CHECK-NEXT: [[BV0_TRUNC:%[0-9]+]]:_(<2 x s16>) = G_TRUNC [[BV0]] 1556 1557 CHECK: [[EXT_K0_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]] 1558 CHECK-NEXT: [[EXT_K1_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]] 1559 1560 CHECK-NEXT: [[BV1:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR_TRUNC [[EXT_K0_1]]:_(s32), [[EXT_K1_1]]:_(s32) 1561 )"; 1562 1563 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1564 } 1565 1566 TEST_F(AArch64GISelMITest, LowerMergeValues) { 1567 setUp(); 1568 if (!TM) 1569 return; 1570 1571 const LLT S32 = LLT::scalar(32); 1572 const LLT S24 = LLT::scalar(24); 1573 const LLT S21 = LLT::scalar(21); 1574 const LLT S16 = LLT::scalar(16); 1575 const LLT S9 = LLT::scalar(9); 1576 const LLT S8 = LLT::scalar(8); 1577 const LLT S3 = LLT::scalar(3); 1578 1579 DefineLegalizerInfo(A, { 1580 getActionDefinitionsBuilder(G_UNMERGE_VALUES) 1581 .widenScalarIf(typeIs(1, LLT::scalar(3)), changeTo(1, LLT::scalar(9))); 1582 }); 1583 1584 AInfo Info(MF->getSubtarget()); 1585 DummyGISelObserver Observer; 1586 LegalizerHelper Helper(*MF, Info, Observer, B); 1587 B.setInsertPt(*EntryMBB, EntryMBB->end()); 1588 1589 // 24 = 3 3 3 3 3 3 3 3 1590 // => 9 1591 // 1592 // This can do 3 merges, but need an extra implicit_def. 1593 SmallVector<Register, 8> Merge0Ops; 1594 for (int I = 0; I != 8; ++I) 1595 Merge0Ops.push_back(B.buildConstant(S3, I).getReg(0)); 1596 1597 auto Merge0 = B.buildMerge(S24, Merge0Ops); 1598 1599 // 21 = 3 3 3 3 3 3 3 1600 // => 9, 2 extra implicit_def needed 1601 // 1602 SmallVector<Register, 8> Merge1Ops; 1603 for (int I = 0; I != 7; ++I) 1604 Merge1Ops.push_back(B.buildConstant(S3, I).getReg(0)); 1605 1606 auto Merge1 = B.buildMerge(S21, Merge1Ops); 1607 1608 SmallVector<Register, 8> Merge2Ops; 1609 for (int I = 0; I != 2; ++I) 1610 Merge2Ops.push_back(B.buildConstant(S8, I).getReg(0)); 1611 1612 auto Merge2 = B.buildMerge(S16, Merge2Ops); 1613 1614 B.setInstr(*Merge0); 1615 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1616 Helper.widenScalar(*Merge0, 1, S9)); 1617 B.setInstr(*Merge1); 1618 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1619 Helper.widenScalar(*Merge1, 1, S9)); 1620 1621 // Request a source size greater than the original destination size. 1622 B.setInstr(*Merge2); 1623 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1624 Helper.widenScalar(*Merge2, 1, S32)); 1625 1626 auto CheckStr = R"( 1627 CHECK: [[K0:%[0-9]+]]:_(s3) = G_CONSTANT i3 0 1628 CHECK-NEXT: [[K1:%[0-9]+]]:_(s3) = G_CONSTANT i3 1 1629 CHECK-NEXT: [[K2:%[0-9]+]]:_(s3) = G_CONSTANT i3 2 1630 CHECK-NEXT: [[K3:%[0-9]+]]:_(s3) = G_CONSTANT i3 3 1631 CHECK-NEXT: [[K4:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4 1632 CHECK-NEXT: [[K5:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3 1633 CHECK-NEXT: [[K6:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2 1634 CHECK-NEXT: [[K7:%[0-9]+]]:_(s3) = G_CONSTANT i3 -1 1635 CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF 1636 CHECK-NEXT: [[MERGE0:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K0]]:_(s3), [[K1]]:_(s3), [[K2]]:_(s3) 1637 CHECK-NEXT: [[MERGE1:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K3]]:_(s3), [[K4]]:_(s3), [[K5]]:_(s3) 1638 CHECK-NEXT: [[MERGE2:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K6]]:_(s3), [[K7]]:_(s3), [[IMPDEF0]]:_(s3) 1639 CHECK-NEXT: [[MERGE3:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE0]]:_(s9), [[MERGE1]]:_(s9), [[MERGE2]]:_(s9) 1640 CHECK-NEXT: (s24) = G_TRUNC [[MERGE3]]:_(s27) 1641 1642 1643 CHECK: [[K8:%[0-9]+]]:_(s3) = G_CONSTANT i3 0 1644 CHECK-NEXT: [[K9:%[0-9]+]]:_(s3) = G_CONSTANT i3 1 1645 CHECK-NEXT: [[K10:%[0-9]+]]:_(s3) = G_CONSTANT i3 2 1646 CHECK-NEXT: [[K11:%[0-9]+]]:_(s3) = G_CONSTANT i3 3 1647 CHECK-NEXT: [[K12:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4 1648 CHECK-NEXT: [[K13:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3 1649 CHECK-NEXT: [[K14:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2 1650 CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF 1651 CHECK-NEXT: [[MERGE4:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K8]]:_(s3), [[K9]]:_(s3), [[K10]]:_(s3) 1652 CHECK-NEXT: [[MERGE5:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K11]]:_(s3), [[K12]]:_(s3), [[K13]]:_(s3) 1653 CHECK-NEXT: [[MERGE6:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K14]]:_(s3), [[IMPDEF1]]:_(s3), [[IMPDEF1]]:_(s3) 1654 CHECK-NEXT: [[MERGE7:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE4]]:_(s9), [[MERGE5]]:_(s9), [[MERGE6]]:_(s9) 1655 CHECK-NEXT: (s21) = G_TRUNC [[MERGE7]]:_(s27) 1656 1657 1658 CHECK: [[K15:%[0-9]+]]:_(s8) = G_CONSTANT i8 0 1659 CHECK-NEXT: [[K16:%[0-9]+]]:_(s8) = G_CONSTANT i8 1 1660 CHECK-NEXT: [[ZEXT_K15:[0-9]+]]:_(s32) = G_ZEXT [[K15]]:_(s8) 1661 CHECK-NEXT: [[ZEXT_K16:[0-9]+]]:_(s32) = G_ZEXT [[K16]]:_(s8) 1662 [[K16:%[0-9]+]]:_(s32) = G_CONSTANT i32 8 1663 [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ZEXT_K16]]:_, [[K16]]:_(s32) 1664 [[OR:%[0-9]+]]:_(s32) = G_OR [[ZEXT_K16]]:_, [[SHL]]:_ 1665 (s16) = G_TRUNC [[OR]]:_(s32) 1666 )"; 1667 1668 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1669 } 1670 1671 TEST_F(AArch64GISelMITest, WidenScalarMergeValuesPointer) { 1672 setUp(); 1673 if (!TM) 1674 return; 1675 1676 DefineLegalizerInfo(A, {}); 1677 1678 AInfo Info(MF->getSubtarget()); 1679 DummyGISelObserver Observer; 1680 LegalizerHelper Helper(*MF, Info, Observer, B); 1681 B.setInsertPt(*EntryMBB, EntryMBB->end()); 1682 1683 const LLT S32 = LLT::scalar(32); 1684 const LLT S64 = LLT::scalar(64); 1685 const LLT P0 = LLT::pointer(0, 64); 1686 1687 auto Lo = B.buildTrunc(S32, Copies[0]); 1688 auto Hi = B.buildTrunc(S32, Copies[1]); 1689 1690 auto Merge = B.buildMerge(P0, {Lo, Hi}); 1691 1692 B.setInstr(*Merge); 1693 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1694 Helper.widenScalar(*Merge, 1, S64)); 1695 1696 auto CheckStr = R"( 1697 CHECK: [[TRUNC0:%[0-9]+]]:_(s32) = G_TRUNC 1698 CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC 1699 CHECK: [[ZEXT_TRUNC0:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC0]] 1700 CHECK: [[ZEXT_TRUNC1:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC1]] 1701 CHECK: [[SHIFT_AMT:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 1702 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT_TRUNC1]]:_, [[SHIFT_AMT]] 1703 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[ZEXT_TRUNC0]]:_, [[SHL]] 1704 CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]:_(s64) 1705 )"; 1706 1707 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1708 } 1709 1710 TEST_F(AArch64GISelMITest, WidenSEXTINREG) { 1711 setUp(); 1712 if (!TM) 1713 return; 1714 1715 // Declare your legalization info 1716 DefineLegalizerInfo(A, { 1717 getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); 1718 }); 1719 // Build Instr 1720 auto MIB = B.buildInstr( 1721 TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)}, 1722 {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}), 1723 uint64_t(8)}); 1724 AInfo Info(MF->getSubtarget()); 1725 DummyGISelObserver Observer; 1726 LegalizerHelper Helper(*MF, Info, Observer, B); 1727 // Perform Legalization 1728 B.setInstr(*MIB); 1729 ASSERT_TRUE(Helper.widenScalar(*MIB, 0, LLT::scalar(64)) == 1730 LegalizerHelper::LegalizeResult::Legalized); 1731 1732 auto CheckStr = R"( 1733 CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC 1734 CHECK: [[T1:%[0-9]+]]:_(s64) = G_ANYEXT [[T0]]:_(s32) 1735 CHECK: [[T2:%[0-9]+]]:_(s64) = G_SEXT_INREG [[T1]]:_, 8 1736 CHECK: [[T3:%[0-9]+]]:_(s32) = G_TRUNC [[T2]]:_(s64) 1737 )"; 1738 1739 // Check 1740 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1741 } 1742 1743 TEST_F(AArch64GISelMITest, NarrowSEXTINREG) { 1744 setUp(); 1745 if (!TM) 1746 return; 1747 1748 // Declare your legalization info, these aren't actually relevant to the test. 1749 DefineLegalizerInfo(A, { 1750 getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); 1751 }); 1752 // Build Instr 1753 auto MIB = B.buildInstr( 1754 TargetOpcode::G_SEXT_INREG, {LLT::scalar(16)}, 1755 {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(16)}, {Copies[0]}), 1756 uint64_t(8)}); 1757 AInfo Info(MF->getSubtarget()); 1758 DummyGISelObserver Observer; 1759 LegalizerHelper Helper(*MF, Info, Observer, B); 1760 // Perform Legalization 1761 B.setInstr(*MIB); 1762 ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(10)) == 1763 LegalizerHelper::LegalizeResult::Legalized); 1764 1765 auto CheckStr = R"( 1766 CHECK: [[T0:%[0-9]+]]:_(s16) = G_TRUNC 1767 CHECK: [[T1:%[0-9]+]]:_(s10) = G_TRUNC [[T0]]:_(s16) 1768 CHECK: [[T2:%[0-9]+]]:_(s10) = G_SEXT_INREG [[T1]]:_, 8 1769 CHECK: [[T3:%[0-9]+]]:_(s16) = G_SEXT [[T2]]:_(s10) 1770 )"; 1771 1772 // Check 1773 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1774 } 1775 1776 TEST_F(AArch64GISelMITest, NarrowSEXTINREG2) { 1777 setUp(); 1778 if (!TM) 1779 return; 1780 1781 // Declare your legalization info, these aren't actually relevant to the test. 1782 DefineLegalizerInfo( 1783 A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); }); 1784 // Build Instr 1785 auto MIB = B.buildInstr( 1786 TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)}, 1787 {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}), 1788 uint64_t(9)}); 1789 AInfo Info(MF->getSubtarget()); 1790 DummyGISelObserver Observer; 1791 LegalizerHelper Helper(*MF, Info, Observer, B); 1792 // Perform Legalization 1793 B.setInstr(*MIB); 1794 ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(8)) == 1795 LegalizerHelper::LegalizeResult::Legalized); 1796 1797 auto CheckStr = R"( 1798 CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC 1799 CHECK: [[T1:%[0-9]+]]:_(s8), [[T2:%[0-9]+]]:_(s8), [[T3:%[0-9]+]]:_(s8), [[T4:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[T0]]:_(s32) 1800 CHECK: [[CST2:%[0-9]+]]:_(s8) = G_CONSTANT i8 7 1801 CHECK: [[T5:%[0-9]+]]:_(s8) = G_SEXT_INREG [[T2]]:_, 1 1802 CHECK: [[T6:%[0-9]+]]:_(s8) = G_ASHR [[T5]]:_, [[CST2]]:_ 1803 CHECK: [[T7:%[0-9]+]]:_(s32) = G_MERGE_VALUES [[T1]]:_(s8), [[T5]]:_(s8), [[T6]]:_(s8), [[T6]]:_(s8) 1804 )"; 1805 1806 // Check 1807 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)); 1808 } 1809 1810 TEST_F(AArch64GISelMITest, LowerSEXTINREG) { 1811 setUp(); 1812 if (!TM) 1813 return; 1814 1815 // Declare your legalization info, these aren't actually relevant to the test. 1816 DefineLegalizerInfo( 1817 A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); }); 1818 // Build Instr 1819 auto MIB = B.buildInstr( 1820 TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)}, 1821 {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}), 1822 uint64_t(8)}); 1823 AInfo Info(MF->getSubtarget()); 1824 DummyGISelObserver Observer; 1825 LegalizerHelper Helper(*MF, Info, Observer, B); 1826 // Perform Legalization 1827 B.setInstr(*MIB); 1828 ASSERT_TRUE(Helper.lower(*MIB, 0, LLT()) == 1829 LegalizerHelper::LegalizeResult::Legalized); 1830 1831 auto CheckStr = R"( 1832 CHECK: [[T1:%[0-9]+]]:_(s32) = G_TRUNC 1833 CHECK: [[CST:%[0-9]+]]:_(s32) = G_CONSTANT i32 24 1834 CHECK: [[T2:%[0-9]+]]:_(s32) = G_SHL [[T1]]:_, [[CST]]:_ 1835 CHECK: [[T3:%[0-9]+]]:_(s32) = G_ASHR [[T2]]:_, [[CST]]:_ 1836 )"; 1837 1838 // Check 1839 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)); 1840 } 1841 1842 TEST_F(AArch64GISelMITest, LibcallFPExt) { 1843 setUp(); 1844 if (!TM) 1845 return; 1846 1847 // Declare your legalization info 1848 DefineLegalizerInfo(A, { 1849 getActionDefinitionsBuilder(G_FPEXT).libcallFor({{s32, s16}, {s128, s64}}); 1850 }); 1851 1852 LLT S16{LLT::scalar(16)}; 1853 LLT S32{LLT::scalar(32)}; 1854 LLT S128{LLT::scalar(128)}; 1855 auto MIBTrunc = B.buildTrunc(S16, Copies[0]); 1856 auto MIBFPExt1 = 1857 B.buildInstr(TargetOpcode::G_FPEXT, {S32}, {MIBTrunc}); 1858 1859 auto MIBFPExt2 = 1860 B.buildInstr(TargetOpcode::G_FPEXT, {S128}, {Copies[1]}); 1861 AInfo Info(MF->getSubtarget()); 1862 DummyGISelObserver Observer; 1863 LegalizerHelper Helper(*MF, Info, Observer, B); 1864 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1865 Helper.libcall(*MIBFPExt1)); 1866 1867 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1868 Helper.libcall(*MIBFPExt2)); 1869 auto CheckStr = R"( 1870 CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC 1871 CHECK: $h0 = COPY [[TRUNC]] 1872 CHECK: BL &__gnu_h2f_ieee 1873 CHECK: $d0 = COPY 1874 CHECK: BL &__extenddftf2 1875 )"; 1876 1877 // Check 1878 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1879 } 1880 1881 TEST_F(AArch64GISelMITest, LibcallFPTrunc) { 1882 setUp(); 1883 if (!TM) 1884 return; 1885 1886 // Declare your legalization info 1887 DefineLegalizerInfo(A, { 1888 getActionDefinitionsBuilder(G_FPTRUNC).libcallFor({{s16, s32}, {s64, s128}}); 1889 }); 1890 1891 LLT S16{LLT::scalar(16)}; 1892 LLT S32{LLT::scalar(32)}; 1893 LLT S64{LLT::scalar(64)}; 1894 LLT S128{LLT::scalar(128)}; 1895 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 1896 auto MIBFPTrunc1 = 1897 B.buildInstr(TargetOpcode::G_FPTRUNC, {S16}, {MIBTrunc}); 1898 1899 auto MIBMerge = B.buildMerge(S128, {Copies[1], Copies[2]}); 1900 1901 auto MIBFPTrunc2 = 1902 B.buildInstr(TargetOpcode::G_FPTRUNC, {S64}, {MIBMerge}); 1903 AInfo Info(MF->getSubtarget()); 1904 DummyGISelObserver Observer; 1905 LegalizerHelper Helper(*MF, Info, Observer, B); 1906 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1907 Helper.libcall(*MIBFPTrunc1)); 1908 1909 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1910 Helper.libcall(*MIBFPTrunc2)); 1911 auto CheckStr = R"( 1912 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 1913 CHECK: $s0 = COPY [[TRUNC]] 1914 CHECK: BL &__gnu_f2h_ieee 1915 CHECK: $q0 = COPY 1916 CHECK: BL &__trunctfdf2 1917 )"; 1918 1919 // Check 1920 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 1921 } 1922 1923 TEST_F(AArch64GISelMITest, LibcallSimple) { 1924 setUp(); 1925 if (!TM) 1926 return; 1927 1928 // Declare your legalization info 1929 DefineLegalizerInfo(A, { 1930 getActionDefinitionsBuilder(G_FADD).libcallFor({s16}); 1931 }); 1932 1933 LLT S16{LLT::scalar(16)}; 1934 auto MIBTrunc = B.buildTrunc(S16, Copies[0]); 1935 auto MIBFADD = 1936 B.buildInstr(TargetOpcode::G_FADD, {S16}, {MIBTrunc, MIBTrunc}); 1937 1938 AInfo Info(MF->getSubtarget()); 1939 DummyGISelObserver Observer; 1940 LegalizerHelper Helper(*MF, Info, Observer, B); 1941 // Make sure we do not crash anymore 1942 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize, 1943 Helper.libcall(*MIBFADD)); 1944 } 1945 1946 TEST_F(AArch64GISelMITest, LibcallSRem) { 1947 setUp(); 1948 if (!TM) 1949 return; 1950 1951 // Declare your legalization info 1952 DefineLegalizerInfo(A, { 1953 getActionDefinitionsBuilder(G_SREM).libcallFor({s32, s64, s128}); 1954 }); 1955 1956 LLT S32{LLT::scalar(32)}; 1957 LLT S64{LLT::scalar(64)}; 1958 LLT S128{LLT::scalar(128)}; 1959 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 1960 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 1961 1962 auto MIBSRem32 = 1963 B.buildInstr(TargetOpcode::G_SREM, {S32}, {MIBTrunc, MIBTrunc}); 1964 auto MIBSRem64 = 1965 B.buildInstr(TargetOpcode::G_SREM, {S64}, {Copies[0], Copies[0]}); 1966 auto MIBSRem128 = 1967 B.buildInstr(TargetOpcode::G_SREM, {S128}, {MIBExt, MIBExt}); 1968 1969 AInfo Info(MF->getSubtarget()); 1970 DummyGISelObserver Observer; 1971 LegalizerHelper Helper(*MF, Info, Observer, B); 1972 1973 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1974 Helper.libcall(*MIBSRem32)); 1975 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1976 Helper.libcall(*MIBSRem64)); 1977 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 1978 Helper.libcall(*MIBSRem128)); 1979 1980 auto CheckStr = R"( 1981 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 1982 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 1983 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 1984 CHECK: $w0 = COPY [[TRUNC]] 1985 CHECK: $w1 = COPY [[TRUNC]] 1986 CHECK: BL &__modsi3 1987 CHECK: $x0 = COPY [[COPY]] 1988 CHECK: $x1 = COPY [[COPY]] 1989 CHECK: BL &__moddi3 1990 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]] 1991 CHECK: $x0 = COPY [[UV]] 1992 CHECK: $x1 = COPY [[UV1]] 1993 CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]] 1994 CHECK: $x2 = COPY [[UV2]] 1995 CHECK: $x3 = COPY [[UV3]] 1996 CHECK: BL &__modti3 1997 )"; 1998 1999 // Check 2000 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2001 } 2002 2003 TEST_F(AArch64GISelMITest, LibcallURem) { 2004 setUp(); 2005 if (!TM) 2006 return; 2007 2008 // Declare your legalization info 2009 DefineLegalizerInfo(A, { 2010 getActionDefinitionsBuilder(G_UREM).libcallFor({s32, s64, s128}); 2011 }); 2012 2013 LLT S32{LLT::scalar(32)}; 2014 LLT S64{LLT::scalar(64)}; 2015 LLT S128{LLT::scalar(128)}; 2016 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2017 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2018 2019 auto MIBURem32 = 2020 B.buildInstr(TargetOpcode::G_UREM, {S32}, {MIBTrunc, MIBTrunc}); 2021 auto MIBURem64 = 2022 B.buildInstr(TargetOpcode::G_UREM, {S64}, {Copies[0], Copies[0]}); 2023 auto MIBURem128 = 2024 B.buildInstr(TargetOpcode::G_UREM, {S128}, {MIBExt, MIBExt}); 2025 2026 AInfo Info(MF->getSubtarget()); 2027 DummyGISelObserver Observer; 2028 LegalizerHelper Helper(*MF, Info, Observer, B); 2029 2030 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2031 Helper.libcall(*MIBURem32)); 2032 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2033 Helper.libcall(*MIBURem64)); 2034 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2035 Helper.libcall(*MIBURem128)); 2036 2037 const auto *CheckStr = R"( 2038 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2039 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2040 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2041 CHECK: $w0 = COPY [[TRUNC]] 2042 CHECK: $w1 = COPY [[TRUNC]] 2043 CHECK: BL &__umodsi3 2044 CHECK: $x0 = COPY [[COPY]] 2045 CHECK: $x1 = COPY [[COPY]] 2046 CHECK: BL &__umoddi3 2047 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]] 2048 CHECK: $x0 = COPY [[UV]] 2049 CHECK: $x1 = COPY [[UV1]] 2050 CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]] 2051 CHECK: $x2 = COPY [[UV2]] 2052 CHECK: $x3 = COPY [[UV3]] 2053 CHECK: BL &__umodti3 2054 )"; 2055 2056 // Check 2057 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2058 } 2059 2060 TEST_F(AArch64GISelMITest, LibcallCtlzZeroUndef) { 2061 setUp(); 2062 if (!TM) 2063 return; 2064 2065 // Declare your legalization info 2066 DefineLegalizerInfo(A, { 2067 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF) 2068 .libcallFor({{s32, s32}, {s64, s64}, {s128, s128}}); 2069 }); 2070 2071 LLT S32{LLT::scalar(32)}; 2072 LLT S64{LLT::scalar(64)}; 2073 LLT S128{LLT::scalar(128)}; 2074 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2075 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2076 2077 auto MIBCtlz32 = 2078 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S32}, {MIBTrunc}); 2079 auto MIBCtlz64 = 2080 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S64}, {Copies[0]}); 2081 auto MIBCtlz128 = 2082 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S128}, {MIBExt}); 2083 2084 AInfo Info(MF->getSubtarget()); 2085 DummyGISelObserver Observer; 2086 LegalizerHelper Helper(*MF, Info, Observer, B); 2087 2088 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2089 Helper.libcall(*MIBCtlz32)); 2090 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2091 Helper.libcall(*MIBCtlz64)); 2092 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2093 Helper.libcall(*MIBCtlz128)); 2094 2095 const auto *CheckStr = R"( 2096 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2097 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2098 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2099 CHECK: $w0 = COPY [[TRUNC]] 2100 CHECK: BL &__clzsi2 2101 CHECK: $x0 = COPY [[COPY]] 2102 CHECK: BL &__clzdi2 2103 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]] 2104 CHECK: $x0 = COPY [[UV]] 2105 CHECK: $x1 = COPY [[UV1]] 2106 CHECK: BL &__clzti2 2107 )"; 2108 2109 // Check 2110 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2111 } 2112 2113 TEST_F(AArch64GISelMITest, LibcallFAdd) { 2114 setUp(); 2115 if (!TM) 2116 return; 2117 2118 // Declare your legalization info 2119 DefineLegalizerInfo(A, { 2120 getActionDefinitionsBuilder(G_FADD).libcallFor({s32, s64, s128}); 2121 }); 2122 2123 LLT S32{LLT::scalar(32)}; 2124 LLT S64{LLT::scalar(64)}; 2125 LLT S128{LLT::scalar(128)}; 2126 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2127 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2128 2129 auto MIBAdd32 = 2130 B.buildInstr(TargetOpcode::G_FADD, {S32}, {MIBTrunc, MIBTrunc}); 2131 auto MIBAdd64 = 2132 B.buildInstr(TargetOpcode::G_FADD, {S64}, {Copies[0], Copies[0]}); 2133 auto MIBAdd128 = B.buildInstr(TargetOpcode::G_FADD, {S128}, {MIBExt, MIBExt}); 2134 2135 AInfo Info(MF->getSubtarget()); 2136 DummyGISelObserver Observer; 2137 LegalizerHelper Helper(*MF, Info, Observer, B); 2138 2139 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2140 Helper.libcall(*MIBAdd32)); 2141 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2142 Helper.libcall(*MIBAdd64)); 2143 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2144 Helper.libcall(*MIBAdd128)); 2145 2146 const auto *CheckStr = R"( 2147 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2148 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2149 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2150 CHECK: $s0 = COPY [[TRUNC]] 2151 CHECK: $s1 = COPY [[TRUNC]] 2152 CHECK: BL &__addsf3 2153 CHECK: $d0 = COPY [[COPY]] 2154 CHECK: $d1 = COPY [[COPY]] 2155 CHECK: BL &__adddf3 2156 CHECK: $q0 = COPY [[ANYEXT]] 2157 CHECK: $q1 = COPY [[ANYEXT]] 2158 CHECK: BL &__addtf3 2159 )"; 2160 2161 // Check 2162 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2163 } 2164 2165 TEST_F(AArch64GISelMITest, LibcallFSub) { 2166 setUp(); 2167 if (!TM) 2168 return; 2169 2170 // Declare your legalization info 2171 DefineLegalizerInfo(A, { 2172 getActionDefinitionsBuilder(G_FSUB).libcallFor({s32, s64, s128}); 2173 }); 2174 2175 LLT S32{LLT::scalar(32)}; 2176 LLT S64{LLT::scalar(64)}; 2177 LLT S128{LLT::scalar(128)}; 2178 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2179 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2180 2181 auto MIBSub32 = 2182 B.buildInstr(TargetOpcode::G_FSUB, {S32}, {MIBTrunc, MIBTrunc}); 2183 auto MIBSub64 = 2184 B.buildInstr(TargetOpcode::G_FSUB, {S64}, {Copies[0], Copies[0]}); 2185 auto MIBSub128 = B.buildInstr(TargetOpcode::G_FSUB, {S128}, {MIBExt, MIBExt}); 2186 2187 AInfo Info(MF->getSubtarget()); 2188 DummyGISelObserver Observer; 2189 LegalizerHelper Helper(*MF, Info, Observer, B); 2190 2191 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2192 Helper.libcall(*MIBSub32)); 2193 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2194 Helper.libcall(*MIBSub64)); 2195 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2196 Helper.libcall(*MIBSub128)); 2197 2198 const auto *CheckStr = R"( 2199 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2200 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2201 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2202 CHECK: $s0 = COPY [[TRUNC]] 2203 CHECK: $s1 = COPY [[TRUNC]] 2204 CHECK: BL &__subsf3 2205 CHECK: $d0 = COPY [[COPY]] 2206 CHECK: $d1 = COPY [[COPY]] 2207 CHECK: BL &__subdf3 2208 CHECK: $q0 = COPY [[ANYEXT]] 2209 CHECK: $q1 = COPY [[ANYEXT]] 2210 CHECK: BL &__subtf3 2211 )"; 2212 2213 // Check 2214 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2215 } 2216 2217 TEST_F(AArch64GISelMITest, LibcallFMul) { 2218 setUp(); 2219 if (!TM) 2220 return; 2221 2222 // Declare your legalization info 2223 DefineLegalizerInfo(A, { 2224 getActionDefinitionsBuilder(G_FMUL).libcallFor({s32, s64, s128}); 2225 }); 2226 2227 LLT S32{LLT::scalar(32)}; 2228 LLT S64{LLT::scalar(64)}; 2229 LLT S128{LLT::scalar(128)}; 2230 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2231 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2232 2233 auto MIBMul32 = 2234 B.buildInstr(TargetOpcode::G_FMUL, {S32}, {MIBTrunc, MIBTrunc}); 2235 auto MIBMul64 = 2236 B.buildInstr(TargetOpcode::G_FMUL, {S64}, {Copies[0], Copies[0]}); 2237 auto MIBMul128 = B.buildInstr(TargetOpcode::G_FMUL, {S128}, {MIBExt, MIBExt}); 2238 2239 AInfo Info(MF->getSubtarget()); 2240 DummyGISelObserver Observer; 2241 LegalizerHelper Helper(*MF, Info, Observer, B); 2242 2243 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2244 Helper.libcall(*MIBMul32)); 2245 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2246 Helper.libcall(*MIBMul64)); 2247 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2248 Helper.libcall(*MIBMul128)); 2249 2250 const auto *CheckStr = R"( 2251 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2252 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2253 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2254 CHECK: $s0 = COPY [[TRUNC]] 2255 CHECK: $s1 = COPY [[TRUNC]] 2256 CHECK: BL &__mulsf3 2257 CHECK: $d0 = COPY [[COPY]] 2258 CHECK: $d1 = COPY [[COPY]] 2259 CHECK: BL &__muldf3 2260 CHECK: $q0 = COPY [[ANYEXT]] 2261 CHECK: $q1 = COPY [[ANYEXT]] 2262 CHECK: BL &__multf3 2263 )"; 2264 2265 // Check 2266 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2267 } 2268 2269 TEST_F(AArch64GISelMITest, LibcallFDiv) { 2270 setUp(); 2271 if (!TM) 2272 return; 2273 2274 // Declare your legalization info 2275 DefineLegalizerInfo(A, { 2276 getActionDefinitionsBuilder(G_FDIV).libcallFor({s32, s64, s128}); 2277 }); 2278 2279 LLT S32{LLT::scalar(32)}; 2280 LLT S64{LLT::scalar(64)}; 2281 LLT S128{LLT::scalar(128)}; 2282 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2283 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2284 2285 auto MIBDiv32 = 2286 B.buildInstr(TargetOpcode::G_FDIV, {S32}, {MIBTrunc, MIBTrunc}); 2287 auto MIBDiv64 = 2288 B.buildInstr(TargetOpcode::G_FDIV, {S64}, {Copies[0], Copies[0]}); 2289 auto MIBDiv128 = B.buildInstr(TargetOpcode::G_FDIV, {S128}, {MIBExt, MIBExt}); 2290 2291 AInfo Info(MF->getSubtarget()); 2292 DummyGISelObserver Observer; 2293 LegalizerHelper Helper(*MF, Info, Observer, B); 2294 2295 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2296 Helper.libcall(*MIBDiv32)); 2297 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2298 Helper.libcall(*MIBDiv64)); 2299 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2300 Helper.libcall(*MIBDiv128)); 2301 2302 const auto *CheckStr = R"( 2303 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2304 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2305 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2306 CHECK: $s0 = COPY [[TRUNC]] 2307 CHECK: $s1 = COPY [[TRUNC]] 2308 CHECK: BL &__divsf3 2309 CHECK: $d0 = COPY [[COPY]] 2310 CHECK: $d1 = COPY [[COPY]] 2311 CHECK: BL &__divdf3 2312 CHECK: $q0 = COPY [[ANYEXT]] 2313 CHECK: $q1 = COPY [[ANYEXT]] 2314 CHECK: BL &__divtf3 2315 )"; 2316 2317 // Check 2318 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2319 } 2320 2321 TEST_F(AArch64GISelMITest, LibcallFExp) { 2322 setUp(); 2323 if (!TM) 2324 return; 2325 2326 // Declare your legalization info 2327 DefineLegalizerInfo(A, { 2328 getActionDefinitionsBuilder(G_FEXP).libcallFor({s32, s64, s128}); 2329 }); 2330 2331 LLT S32{LLT::scalar(32)}; 2332 LLT S64{LLT::scalar(64)}; 2333 LLT S128{LLT::scalar(128)}; 2334 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2335 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2336 2337 auto MIBExp32 = B.buildInstr(TargetOpcode::G_FEXP, {S32}, {MIBTrunc}); 2338 auto MIBExp64 = B.buildInstr(TargetOpcode::G_FEXP, {S64}, {Copies[0]}); 2339 auto MIBExp128 = B.buildInstr(TargetOpcode::G_FEXP, {S128}, {MIBExt}); 2340 2341 AInfo Info(MF->getSubtarget()); 2342 DummyGISelObserver Observer; 2343 LegalizerHelper Helper(*MF, Info, Observer, B); 2344 2345 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2346 Helper.libcall(*MIBExp32)); 2347 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2348 Helper.libcall(*MIBExp64)); 2349 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2350 Helper.libcall(*MIBExp128)); 2351 2352 const auto *CheckStr = R"( 2353 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2354 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2355 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2356 CHECK: $s0 = COPY [[TRUNC]] 2357 CHECK: BL &expf 2358 CHECK: $d0 = COPY [[COPY]] 2359 CHECK: BL &exp 2360 CHECK: $q0 = COPY [[ANYEXT]] 2361 CHECK: BL &expl 2362 )"; 2363 2364 // Check 2365 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2366 } 2367 2368 TEST_F(AArch64GISelMITest, LibcallFExp2) { 2369 setUp(); 2370 if (!TM) 2371 return; 2372 2373 // Declare your legalization info 2374 DefineLegalizerInfo(A, { 2375 getActionDefinitionsBuilder(G_FEXP2).libcallFor({s32, s64, s128}); 2376 }); 2377 2378 LLT S32{LLT::scalar(32)}; 2379 LLT S64{LLT::scalar(64)}; 2380 LLT S128{LLT::scalar(128)}; 2381 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2382 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2383 2384 auto MIBExp232 = B.buildInstr(TargetOpcode::G_FEXP2, {S32}, {MIBTrunc}); 2385 auto MIBExp264 = B.buildInstr(TargetOpcode::G_FEXP2, {S64}, {Copies[0]}); 2386 auto MIBExp2128 = B.buildInstr(TargetOpcode::G_FEXP2, {S128}, {MIBExt}); 2387 2388 AInfo Info(MF->getSubtarget()); 2389 DummyGISelObserver Observer; 2390 LegalizerHelper Helper(*MF, Info, Observer, B); 2391 2392 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2393 Helper.libcall(*MIBExp232)); 2394 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2395 Helper.libcall(*MIBExp264)); 2396 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2397 Helper.libcall(*MIBExp2128)); 2398 2399 const auto *CheckStr = R"( 2400 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2401 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2402 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2403 CHECK: $s0 = COPY [[TRUNC]] 2404 CHECK: BL &exp2f 2405 CHECK: $d0 = COPY [[COPY]] 2406 CHECK: BL &exp2 2407 CHECK: $q0 = COPY [[ANYEXT]] 2408 CHECK: BL &exp2l 2409 )"; 2410 2411 // Check 2412 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2413 } 2414 2415 TEST_F(AArch64GISelMITest, LibcallFRem) { 2416 setUp(); 2417 if (!TM) 2418 return; 2419 2420 // Declare your legalization info 2421 DefineLegalizerInfo(A, { 2422 getActionDefinitionsBuilder(G_FREM).libcallFor({s32, s64, s128}); 2423 }); 2424 2425 LLT S32{LLT::scalar(32)}; 2426 LLT S64{LLT::scalar(64)}; 2427 LLT S128{LLT::scalar(128)}; 2428 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2429 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2430 2431 auto MIBFRem32 = B.buildInstr(TargetOpcode::G_FREM, {S32}, {MIBTrunc}); 2432 auto MIBFRem64 = B.buildInstr(TargetOpcode::G_FREM, {S64}, {Copies[0]}); 2433 auto MIBFRem128 = B.buildInstr(TargetOpcode::G_FREM, {S128}, {MIBExt}); 2434 2435 AInfo Info(MF->getSubtarget()); 2436 DummyGISelObserver Observer; 2437 LegalizerHelper Helper(*MF, Info, Observer, B); 2438 2439 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2440 Helper.libcall(*MIBFRem32)); 2441 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2442 Helper.libcall(*MIBFRem64)); 2443 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2444 Helper.libcall(*MIBFRem128)); 2445 2446 const auto *CheckStr = R"( 2447 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2448 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2449 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2450 CHECK: $s0 = COPY [[TRUNC]] 2451 CHECK: BL &fmodf 2452 CHECK: $d0 = COPY [[COPY]] 2453 CHECK: BL &fmod 2454 CHECK: $q0 = COPY [[ANYEXT]] 2455 CHECK: BL &fmodl 2456 )"; 2457 2458 // Check 2459 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2460 } 2461 2462 TEST_F(AArch64GISelMITest, LibcallFPow) { 2463 setUp(); 2464 if (!TM) 2465 return; 2466 2467 // Declare your legalization info 2468 DefineLegalizerInfo(A, { 2469 getActionDefinitionsBuilder(G_FPOW).libcallFor({s32, s64, s128}); 2470 }); 2471 2472 LLT S32{LLT::scalar(32)}; 2473 LLT S64{LLT::scalar(64)}; 2474 LLT S128{LLT::scalar(128)}; 2475 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2476 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2477 2478 auto MIBPow32 = B.buildInstr(TargetOpcode::G_FPOW, {S32}, {MIBTrunc}); 2479 auto MIBPow64 = B.buildInstr(TargetOpcode::G_FPOW, {S64}, {Copies[0]}); 2480 auto MIBPow128 = B.buildInstr(TargetOpcode::G_FPOW, {S128}, {MIBExt}); 2481 2482 AInfo Info(MF->getSubtarget()); 2483 DummyGISelObserver Observer; 2484 LegalizerHelper Helper(*MF, Info, Observer, B); 2485 2486 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2487 Helper.libcall(*MIBPow32)); 2488 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2489 Helper.libcall(*MIBPow64)); 2490 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2491 Helper.libcall(*MIBPow128)); 2492 2493 const auto *CheckStr = R"( 2494 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2495 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2496 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2497 CHECK: $s0 = COPY [[TRUNC]] 2498 CHECK: BL &powf 2499 CHECK: $d0 = COPY [[COPY]] 2500 CHECK: BL &pow 2501 CHECK: $q0 = COPY [[ANYEXT]] 2502 CHECK: BL &powl 2503 )"; 2504 2505 // Check 2506 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2507 } 2508 2509 TEST_F(AArch64GISelMITest, LibcallFMa) { 2510 setUp(); 2511 if (!TM) 2512 return; 2513 2514 // Declare your legalization info 2515 DefineLegalizerInfo(A, { 2516 getActionDefinitionsBuilder(G_FMA).libcallFor({s32, s64, s128}); 2517 }); 2518 2519 LLT S32{LLT::scalar(32)}; 2520 LLT S64{LLT::scalar(64)}; 2521 LLT S128{LLT::scalar(128)}; 2522 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2523 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2524 2525 auto MIBMa32 = B.buildInstr(TargetOpcode::G_FMA, {S32}, {MIBTrunc, MIBTrunc}); 2526 auto MIBMa64 = 2527 B.buildInstr(TargetOpcode::G_FMA, {S64}, {Copies[0], Copies[0]}); 2528 auto MIBMa128 = B.buildInstr(TargetOpcode::G_FMA, {S128}, {MIBExt, MIBExt}); 2529 2530 AInfo Info(MF->getSubtarget()); 2531 DummyGISelObserver Observer; 2532 LegalizerHelper Helper(*MF, Info, Observer, B); 2533 2534 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2535 Helper.libcall(*MIBMa32)); 2536 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2537 Helper.libcall(*MIBMa64)); 2538 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2539 Helper.libcall(*MIBMa128)); 2540 2541 const auto *CheckStr = R"( 2542 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2543 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2544 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2545 CHECK: $s0 = COPY [[TRUNC]] 2546 CHECK: BL &fmaf 2547 CHECK: $d0 = COPY [[COPY]] 2548 CHECK: BL &fma 2549 CHECK: $q0 = COPY [[ANYEXT]] 2550 CHECK: BL &fmal 2551 )"; 2552 2553 // Check 2554 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2555 } 2556 2557 TEST_F(AArch64GISelMITest, LibcallFCeil) { 2558 setUp(); 2559 if (!TM) 2560 return; 2561 2562 // Declare your legalization info 2563 DefineLegalizerInfo(A, { 2564 getActionDefinitionsBuilder(G_FCEIL).libcallFor({s32, s64, s128}); 2565 }); 2566 2567 LLT S32{LLT::scalar(32)}; 2568 LLT S64{LLT::scalar(64)}; 2569 LLT S128{LLT::scalar(128)}; 2570 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2571 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2572 2573 auto MIBCeil32 = B.buildInstr(TargetOpcode::G_FCEIL, {S32}, {MIBTrunc}); 2574 auto MIBCeil64 = B.buildInstr(TargetOpcode::G_FCEIL, {S64}, {Copies[0]}); 2575 auto MIBCeil128 = B.buildInstr(TargetOpcode::G_FCEIL, {S128}, {MIBExt}); 2576 2577 AInfo Info(MF->getSubtarget()); 2578 DummyGISelObserver Observer; 2579 LegalizerHelper Helper(*MF, Info, Observer, B); 2580 2581 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2582 Helper.libcall(*MIBCeil32)); 2583 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2584 Helper.libcall(*MIBCeil64)); 2585 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2586 Helper.libcall(*MIBCeil128)); 2587 2588 const auto *CheckStr = R"( 2589 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2590 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2591 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2592 CHECK: $s0 = COPY [[TRUNC]] 2593 CHECK: BL &ceilf 2594 CHECK: $d0 = COPY [[COPY]] 2595 CHECK: BL &ceil 2596 CHECK: $q0 = COPY [[ANYEXT]] 2597 CHECK: BL &ceill 2598 )"; 2599 2600 // Check 2601 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2602 } 2603 2604 TEST_F(AArch64GISelMITest, LibcallFFloor) { 2605 setUp(); 2606 if (!TM) 2607 return; 2608 2609 // Declare your legalization info 2610 DefineLegalizerInfo(A, { 2611 getActionDefinitionsBuilder(G_FFLOOR).libcallFor({s32, s64, s128}); 2612 }); 2613 2614 LLT S32{LLT::scalar(32)}; 2615 LLT S64{LLT::scalar(64)}; 2616 LLT S128{LLT::scalar(128)}; 2617 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2618 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2619 2620 auto MIBFloor32 = B.buildInstr(TargetOpcode::G_FFLOOR, {S32}, {MIBTrunc}); 2621 auto MIBFloor64 = B.buildInstr(TargetOpcode::G_FFLOOR, {S64}, {Copies[0]}); 2622 auto MIBFloor128 = B.buildInstr(TargetOpcode::G_FFLOOR, {S128}, {MIBExt}); 2623 2624 AInfo Info(MF->getSubtarget()); 2625 DummyGISelObserver Observer; 2626 LegalizerHelper Helper(*MF, Info, Observer, B); 2627 2628 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2629 Helper.libcall(*MIBFloor32)); 2630 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2631 Helper.libcall(*MIBFloor64)); 2632 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2633 Helper.libcall(*MIBFloor128)); 2634 2635 const auto *CheckStr = R"( 2636 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2637 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2638 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2639 CHECK: $s0 = COPY [[TRUNC]] 2640 CHECK: BL &floorf 2641 CHECK: $d0 = COPY [[COPY]] 2642 CHECK: BL &floor 2643 CHECK: $q0 = COPY [[ANYEXT]] 2644 CHECK: BL &floorl 2645 )"; 2646 2647 // Check 2648 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2649 } 2650 2651 TEST_F(AArch64GISelMITest, LibcallFMinNum) { 2652 setUp(); 2653 if (!TM) 2654 return; 2655 2656 // Declare your legalization info 2657 DefineLegalizerInfo(A, { 2658 getActionDefinitionsBuilder(G_FMINNUM).libcallFor({s32, s64, s128}); 2659 }); 2660 2661 LLT S32{LLT::scalar(32)}; 2662 LLT S64{LLT::scalar(64)}; 2663 LLT S128{LLT::scalar(128)}; 2664 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2665 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2666 2667 auto MIBMin32 = B.buildFMinNum(S32, MIBTrunc, MIBTrunc); 2668 auto MIBMin64 = B.buildFMinNum(S64, Copies[0], Copies[0]); 2669 auto MIBMin128 = B.buildFMinNum(S128, MIBExt, MIBExt); 2670 2671 AInfo Info(MF->getSubtarget()); 2672 DummyGISelObserver Observer; 2673 LegalizerHelper Helper(*MF, Info, Observer, B); 2674 2675 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2676 Helper.libcall(*MIBMin32)); 2677 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2678 Helper.libcall(*MIBMin64)); 2679 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2680 Helper.libcall(*MIBMin128)); 2681 2682 const auto *CheckStr = R"( 2683 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2684 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2685 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2686 CHECK: $s0 = COPY [[TRUNC]] 2687 CHECK: $s1 = COPY [[TRUNC]] 2688 CHECK: BL &fminf 2689 CHECK: $d0 = COPY [[COPY]] 2690 CHECK: $d1 = COPY [[COPY]] 2691 CHECK: BL &fmin 2692 CHECK: $q0 = COPY [[ANYEXT]] 2693 CHECK: $q1 = COPY [[ANYEXT]] 2694 CHECK: BL &fminl 2695 )"; 2696 2697 // Check 2698 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2699 } 2700 2701 TEST_F(AArch64GISelMITest, LibcallFMaxNum) { 2702 setUp(); 2703 if (!TM) 2704 return; 2705 2706 // Declare your legalization info 2707 DefineLegalizerInfo(A, { 2708 getActionDefinitionsBuilder(G_FMAXNUM).libcallFor({s32, s64, s128}); 2709 }); 2710 2711 LLT S32{LLT::scalar(32)}; 2712 LLT S64{LLT::scalar(64)}; 2713 LLT S128{LLT::scalar(128)}; 2714 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2715 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2716 2717 auto MIBMax32 = B.buildFMaxNum(S32, MIBTrunc, MIBTrunc); 2718 auto MIBMax64 = B.buildFMaxNum(S64, Copies[0], Copies[0]); 2719 auto MIBMax128 = B.buildFMaxNum(S128, MIBExt, MIBExt); 2720 2721 AInfo Info(MF->getSubtarget()); 2722 DummyGISelObserver Observer; 2723 LegalizerHelper Helper(*MF, Info, Observer, B); 2724 2725 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2726 Helper.libcall(*MIBMax32)); 2727 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2728 Helper.libcall(*MIBMax64)); 2729 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2730 Helper.libcall(*MIBMax128)); 2731 2732 const auto *CheckStr = R"( 2733 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2734 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2735 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2736 CHECK: $s0 = COPY [[TRUNC]] 2737 CHECK: $s1 = COPY [[TRUNC]] 2738 CHECK: BL &fmaxf 2739 CHECK: $d0 = COPY [[COPY]] 2740 CHECK: $d1 = COPY [[COPY]] 2741 CHECK: BL &fmax 2742 CHECK: $q0 = COPY [[ANYEXT]] 2743 CHECK: $q1 = COPY [[ANYEXT]] 2744 CHECK: BL &fmaxl 2745 )"; 2746 2747 // Check 2748 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2749 } 2750 2751 TEST_F(AArch64GISelMITest, LibcallFSqrt) { 2752 setUp(); 2753 if (!TM) 2754 return; 2755 2756 // Declare your legalization info 2757 DefineLegalizerInfo(A, { 2758 getActionDefinitionsBuilder(G_FSQRT).libcallFor({s32, s64, s128}); 2759 }); 2760 2761 LLT S32{LLT::scalar(32)}; 2762 LLT S64{LLT::scalar(64)}; 2763 LLT S128{LLT::scalar(128)}; 2764 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2765 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2766 2767 auto MIBSqrt32 = B.buildInstr(TargetOpcode::G_FSQRT, {S32}, {MIBTrunc}); 2768 auto MIBSqrt64 = B.buildInstr(TargetOpcode::G_FSQRT, {S64}, {Copies[0]}); 2769 auto MIBSqrt128 = B.buildInstr(TargetOpcode::G_FSQRT, {S128}, {MIBExt}); 2770 2771 AInfo Info(MF->getSubtarget()); 2772 DummyGISelObserver Observer; 2773 LegalizerHelper Helper(*MF, Info, Observer, B); 2774 2775 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2776 Helper.libcall(*MIBSqrt32)); 2777 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2778 Helper.libcall(*MIBSqrt64)); 2779 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2780 Helper.libcall(*MIBSqrt128)); 2781 2782 const auto *CheckStr = R"( 2783 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2784 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2785 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2786 CHECK: $s0 = COPY [[TRUNC]] 2787 CHECK: BL &sqrtf 2788 CHECK: $d0 = COPY [[COPY]] 2789 CHECK: BL &sqrt 2790 CHECK: $q0 = COPY [[ANYEXT]] 2791 CHECK: BL &sqrtl 2792 )"; 2793 2794 // Check 2795 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2796 } 2797 2798 TEST_F(AArch64GISelMITest, LibcallFRint) { 2799 setUp(); 2800 if (!TM) 2801 return; 2802 2803 // Declare your legalization info 2804 DefineLegalizerInfo(A, { 2805 getActionDefinitionsBuilder(G_FRINT).libcallFor({s32, s64, s128}); 2806 }); 2807 2808 LLT S32{LLT::scalar(32)}; 2809 LLT S64{LLT::scalar(64)}; 2810 LLT S128{LLT::scalar(128)}; 2811 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2812 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2813 2814 auto MIBRint32 = B.buildInstr(TargetOpcode::G_FRINT, {S32}, {MIBTrunc}); 2815 auto MIBRint64 = B.buildInstr(TargetOpcode::G_FRINT, {S64}, {Copies[0]}); 2816 auto MIBRint128 = B.buildInstr(TargetOpcode::G_FRINT, {S128}, {MIBExt}); 2817 2818 AInfo Info(MF->getSubtarget()); 2819 DummyGISelObserver Observer; 2820 LegalizerHelper Helper(*MF, Info, Observer, B); 2821 2822 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2823 Helper.libcall(*MIBRint32)); 2824 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2825 Helper.libcall(*MIBRint64)); 2826 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2827 Helper.libcall(*MIBRint128)); 2828 2829 const auto *CheckStr = R"( 2830 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2831 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2832 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2833 CHECK: $s0 = COPY [[TRUNC]] 2834 CHECK: BL &rintf 2835 CHECK: $d0 = COPY [[COPY]] 2836 CHECK: BL &rint 2837 CHECK: $q0 = COPY [[ANYEXT]] 2838 CHECK: BL &rintl 2839 )"; 2840 2841 // Check 2842 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2843 } 2844 2845 TEST_F(AArch64GISelMITest, LibcallFNearbyInt) { 2846 setUp(); 2847 if (!TM) 2848 return; 2849 2850 // Declare your legalization info 2851 DefineLegalizerInfo(A, { 2852 getActionDefinitionsBuilder(G_FNEARBYINT).libcallFor({s32, s64, s128}); 2853 }); 2854 2855 LLT S32{LLT::scalar(32)}; 2856 LLT S64{LLT::scalar(64)}; 2857 LLT S128{LLT::scalar(128)}; 2858 auto MIBTrunc = B.buildTrunc(S32, Copies[0]); 2859 auto MIBExt = B.buildAnyExt(S128, Copies[0]); 2860 2861 auto MIBNearbyInt32 = 2862 B.buildInstr(TargetOpcode::G_FNEARBYINT, {S32}, {MIBTrunc}); 2863 auto MIBNearbyInt64 = 2864 B.buildInstr(TargetOpcode::G_FNEARBYINT, {S64}, {Copies[0]}); 2865 auto MIBNearbyInt128 = 2866 B.buildInstr(TargetOpcode::G_FNEARBYINT, {S128}, {MIBExt}); 2867 2868 AInfo Info(MF->getSubtarget()); 2869 DummyGISelObserver Observer; 2870 LegalizerHelper Helper(*MF, Info, Observer, B); 2871 2872 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2873 Helper.libcall(*MIBNearbyInt32)); 2874 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2875 Helper.libcall(*MIBNearbyInt64)); 2876 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2877 Helper.libcall(*MIBNearbyInt128)); 2878 2879 const auto *CheckStr = R"( 2880 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 2881 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC 2882 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT 2883 CHECK: $s0 = COPY [[TRUNC]] 2884 CHECK: BL &nearbyintf 2885 CHECK: $d0 = COPY [[COPY]] 2886 CHECK: BL &nearbyint 2887 CHECK: $q0 = COPY [[ANYEXT]] 2888 CHECK: BL &nearbyintl 2889 )"; 2890 2891 // Check 2892 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2893 } 2894 2895 TEST_F(AArch64GISelMITest, NarrowScalarExtract) { 2896 setUp(); 2897 if (!TM) 2898 return; 2899 2900 // Declare your legalization info 2901 DefineLegalizerInfo(A, { 2902 getActionDefinitionsBuilder(G_UNMERGE_VALUES).legalFor({{s32, s64}}); 2903 getActionDefinitionsBuilder(G_EXTRACT).legalForTypeWithAnyImm({{s16, s32}}); 2904 }); 2905 2906 LLT S16{LLT::scalar(16)}; 2907 LLT S32{LLT::scalar(32)}; 2908 2909 auto MIBExtractS32 = B.buildExtract(S32, Copies[1], 32); 2910 auto MIBExtractS16 = B.buildExtract(S16, Copies[1], 0); 2911 2912 AInfo Info(MF->getSubtarget()); 2913 DummyGISelObserver Observer; 2914 LegalizerHelper Helper(*MF, Info, Observer, B); 2915 2916 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2917 Helper.narrowScalar(*MIBExtractS32, 1, S32)); 2918 2919 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2920 Helper.narrowScalar(*MIBExtractS16, 1, S32)); 2921 2922 const auto *CheckStr = R"( 2923 CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES 2924 CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[UV1]] 2925 CHECK: [[UV3:%[0-9]+]]:_(s32), [[UV4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES 2926 CHECK: [[EXTR:%[0-9]+]]:_(s16) = G_EXTRACT [[UV3]]:_(s32), 0 2927 CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[EXTR]] 2928 )"; 2929 2930 // Check 2931 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 2932 } 2933 2934 TEST_F(AArch64GISelMITest, LowerInsert) { 2935 setUp(); 2936 if (!TM) 2937 return; 2938 2939 // Declare your legalization info 2940 DefineLegalizerInfo(A, { getActionDefinitionsBuilder(G_INSERT).lower(); }); 2941 2942 LLT S32{LLT::scalar(32)}; 2943 LLT S64{LLT::scalar(64)}; 2944 LLT P0{LLT::pointer(0, 64)}; 2945 LLT P1{LLT::pointer(1, 32)}; 2946 LLT V2S32{LLT::vector(2, 32)}; 2947 2948 auto TruncS32 = B.buildTrunc(S32, Copies[0]); 2949 auto IntToPtrP0 = B.buildIntToPtr(P0, Copies[0]); 2950 auto IntToPtrP1 = B.buildIntToPtr(P1, TruncS32); 2951 auto BitcastV2S32 = B.buildBitcast(V2S32, Copies[0]); 2952 2953 auto InsertS64S32 = B.buildInsert(S64, Copies[0], TruncS32, 0); 2954 auto InsertS64P1 = B.buildInsert(S64, Copies[0], IntToPtrP1, 8); 2955 auto InsertP0S32 = B.buildInsert(P0, IntToPtrP0, TruncS32, 16); 2956 auto InsertP0P1 = B.buildInsert(P0, IntToPtrP0, IntToPtrP1, 4); 2957 auto InsertV2S32S32 = B.buildInsert(V2S32, BitcastV2S32, TruncS32, 32); 2958 auto InsertV2S32P1 = B.buildInsert(V2S32, BitcastV2S32, IntToPtrP1, 0); 2959 2960 AInfo Info(MF->getSubtarget()); 2961 DummyGISelObserver Observer; 2962 LegalizerHelper Helper(*MF, Info, Observer, B); 2963 2964 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2965 Helper.lower(*InsertS64S32, 0, LLT{})); 2966 2967 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2968 Helper.lower(*InsertS64P1, 0, LLT{})); 2969 2970 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2971 Helper.lower(*InsertP0S32, 0, LLT{})); 2972 2973 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2974 Helper.lower(*InsertP0P1, 0, LLT{})); 2975 2976 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 2977 Helper.lower(*InsertV2S32S32, 0, LLT{})); 2978 2979 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize, 2980 Helper.lower(*InsertV2S32P1, 0, LLT{})); 2981 2982 const auto *CheckStr = R"( 2983 CHECK: [[S64:%[0-9]+]]:_(s64) = COPY 2984 CHECK: [[S32:%[0-9]+]]:_(s32) = G_TRUNC [[S64]] 2985 CHECK: [[P0:%[0-9]+]]:_(p0) = G_INTTOPTR [[S64]] 2986 CHECK: [[P1:%[0-9]+]]:_(p1) = G_INTTOPTR [[S32]] 2987 CHECK: [[V2S32:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[S64]] 2988 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]] 2989 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT 2990 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_ 2991 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[ZEXT]]:_ 2992 2993 CHECK: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]] 2994 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT]] 2995 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT 2996 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64) 2997 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT 2998 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_ 2999 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_ 3000 3001 CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]] 3002 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]] 3003 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT 3004 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64) 3005 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT 3006 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_ 3007 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_ 3008 CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]] 3009 3010 CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]] 3011 CHECK: [[PTRTOINT1:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]] 3012 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT1]] 3013 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT 3014 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64) 3015 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT 3016 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_ 3017 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_ 3018 CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]] 3019 3020 CHECK: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[V2S32]] 3021 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]] 3022 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT 3023 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64) 3024 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT 3025 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[BITCAST]]:_, [[C]]:_ 3026 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_ 3027 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[OR]] 3028 )"; 3029 3030 // Check 3031 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3032 } 3033 3034 // Test lowering of G_FFLOOR 3035 TEST_F(AArch64GISelMITest, LowerFFloor) { 3036 setUp(); 3037 if (!TM) 3038 return; 3039 3040 // Declare your legalization info 3041 DefineLegalizerInfo(A, {}); 3042 // Build Instr 3043 auto Floor = B.buildFFloor(LLT::scalar(64), Copies[0], MachineInstr::MIFlag::FmNoInfs); 3044 AInfo Info(MF->getSubtarget()); 3045 DummyGISelObserver Observer; 3046 LegalizerHelper Helper(*MF, Info, Observer, B); 3047 // Perform Legalization 3048 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3049 Helper.lower(*Floor, 0, LLT())); 3050 3051 auto CheckStr = R"( 3052 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 3053 CHECK: [[TRUNC:%[0-9]+]]:_(s64) = ninf G_INTRINSIC_TRUNC [[COPY]] 3054 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_FCONSTANT double 0.000000e+00 3055 CHECK: [[CMP0:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(olt), [[COPY]]:_(s64), [[ZERO]]:_ 3056 CHECK: [[CMP1:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(one), [[COPY]]:_(s64), [[TRUNC]]:_ 3057 CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[CMP0]]:_, [[CMP1]]:_ 3058 CHECK: [[ITOFP:%[0-9]+]]:_(s64) = G_SITOFP [[AND]] 3059 = ninf G_FADD [[TRUNC]]:_, [[ITOFP]]:_ 3060 )"; 3061 3062 // Check 3063 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3064 } 3065 3066 // Test lowering of G_BSWAP 3067 TEST_F(AArch64GISelMITest, LowerBSWAP) { 3068 setUp(); 3069 if (!TM) 3070 return; 3071 3072 DefineLegalizerInfo(A, {}); 3073 3074 // Make sure vector lowering doesn't assert. 3075 auto Cast = B.buildBitcast(LLT::vector(2, 32), Copies[0]); 3076 auto BSwap = B.buildBSwap(LLT::vector(2, 32), Cast); 3077 AInfo Info(MF->getSubtarget()); 3078 DummyGISelObserver Observer; 3079 LegalizerHelper Helper(*MF, Info, Observer, B); 3080 // Perform Legalization 3081 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3082 Helper.lower(*BSwap, 0, LLT())); 3083 3084 auto CheckStr = R"( 3085 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 3086 CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]] 3087 CHECK: [[K24:%[0-9]+]]:_(s32) = G_CONSTANT i32 24 3088 CHECK: [[SPLAT24:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K24]]:_(s32), [[K24]]:_(s32) 3089 CHECK: [[SHL0:%[0-9]+]]:_(<2 x s32>) = G_SHL [[VEC]]:_, [[SPLAT24]] 3090 CHECK: [[SHR0:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT24]] 3091 CHECK: [[OR0:%[0-9]+]]:_(<2 x s32>) = G_OR [[SHR0]]:_, [[SHL0]]:_ 3092 CHECK: [[KMASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280 3093 CHECK: [[SPLATMASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[KMASK]]:_(s32), [[KMASK]]:_(s32) 3094 CHECK: [[K8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8 3095 CHECK: [[SPLAT8:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K8]]:_(s32), [[K8]]:_(s32) 3096 CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VEC]]:_, [[SPLATMASK]]:_ 3097 CHECK: [[SHL1:%[0-9]+]]:_(<2 x s32>) = G_SHL [[AND0]]:_, [[SPLAT8]] 3098 CHECK: [[OR1:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR0]]:_, [[SHL1]]:_ 3099 CHECK: [[SHR1:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT8]] 3100 CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[SHR1]]:_, [[SPLATMASK]]:_ 3101 CHECK: [[BSWAP:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR1]]:_, [[AND1]]:_ 3102 )"; 3103 3104 // Check 3105 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3106 } 3107 3108 // Test lowering of G_SDIVREM into G_SDIV and G_SREM 3109 TEST_F(AArch64GISelMITest, LowerSDIVREM) { 3110 setUp(); 3111 if (!TM) 3112 return; 3113 3114 // Declare your legalization info 3115 DefineLegalizerInfo( 3116 A, { getActionDefinitionsBuilder(G_SDIVREM).lowerFor({s64}); }); 3117 3118 LLT S64{LLT::scalar(64)}; 3119 3120 // Build Instr 3121 auto SDivrem = 3122 B.buildInstr(TargetOpcode::G_SDIVREM, {S64, S64}, {Copies[0], Copies[1]}); 3123 AInfo Info(MF->getSubtarget()); 3124 DummyGISelObserver Observer; 3125 LegalizerHelper Helper(*MF, Info, Observer, B); 3126 // Perform Legalization 3127 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3128 Helper.lower(*SDivrem, 0, S64)); 3129 3130 const auto *CheckStr = R"( 3131 CHECK: [[DIV:%[0-9]+]]:_(s64) = G_SDIV %0:_, %1:_ 3132 CHECK: [[REM:%[0-9]+]]:_(s64) = G_SREM %0:_, %1:_ 3133 )"; 3134 3135 // Check 3136 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3137 } 3138 3139 // Test lowering of G_UDIVREM into G_UDIV and G_UREM 3140 TEST_F(AArch64GISelMITest, LowerUDIVREM) { 3141 setUp(); 3142 if (!TM) 3143 return; 3144 3145 // Declare your legalization info 3146 DefineLegalizerInfo( 3147 A, { getActionDefinitionsBuilder(G_UDIVREM).lowerFor({s64}); }); 3148 3149 LLT S64{LLT::scalar(64)}; 3150 3151 // Build Instr 3152 auto UDivrem = 3153 B.buildInstr(TargetOpcode::G_UDIVREM, {S64, S64}, {Copies[0], Copies[1]}); 3154 AInfo Info(MF->getSubtarget()); 3155 DummyGISelObserver Observer; 3156 LegalizerHelper Helper(*MF, Info, Observer, B); 3157 // Perform Legalization 3158 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3159 Helper.lower(*UDivrem, 0, S64)); 3160 3161 const auto *CheckStr = R"( 3162 CHECK: [[DIV:%[0-9]+]]:_(s64) = G_UDIV %0:_, %1:_ 3163 CHECK: [[REM:%[0-9]+]]:_(s64) = G_UREM %0:_, %1:_ 3164 )"; 3165 3166 // Check 3167 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3168 } 3169 3170 // Test widening of G_UNMERGE_VALUES 3171 TEST_F(AArch64GISelMITest, WidenUnmerge) { 3172 setUp(); 3173 if (!TM) 3174 return; 3175 3176 DefineLegalizerInfo(A, {}); 3177 3178 // Check that widening G_UNMERGE_VALUES to a larger type than the source type 3179 // works as expected 3180 LLT P0{LLT::pointer(0, 64)}; 3181 LLT S32{LLT::scalar(32)}; 3182 LLT S96{LLT::scalar(96)}; 3183 3184 auto IntToPtr = B.buildIntToPtr(P0, Copies[0]); 3185 auto UnmergePtr = B.buildUnmerge(S32, IntToPtr); 3186 auto UnmergeScalar = B.buildUnmerge(S32, Copies[0]); 3187 3188 AInfo Info(MF->getSubtarget()); 3189 DummyGISelObserver Observer; 3190 LegalizerHelper Helper(*MF, Info, Observer, B); 3191 3192 // Perform Legalization 3193 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3194 Helper.widenScalar(*UnmergePtr, 0, S96)); 3195 3196 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3197 Helper.widenScalar(*UnmergeScalar, 0, S96)); 3198 3199 const auto *CheckStr = R"( 3200 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 3201 CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]] 3202 CHECK: [[INT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR]] 3203 CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[INT]] 3204 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]] 3205 CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32 3206 CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]] 3207 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]] 3208 CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY]] 3209 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]] 3210 CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32 3211 CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]] 3212 CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]] 3213 )"; 3214 3215 // Check 3216 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3217 } 3218 3219 TEST_F(AArch64GISelMITest, BitcastLoad) { 3220 setUp(); 3221 if (!TM) 3222 return; 3223 3224 LLT P0 = LLT::pointer(0, 64); 3225 LLT S32 = LLT::scalar(32); 3226 LLT V4S8 = LLT::vector(4, 8); 3227 auto Ptr = B.buildUndef(P0); 3228 3229 DefineLegalizerInfo(A, {}); 3230 3231 MachineMemOperand *MMO = B.getMF().getMachineMemOperand( 3232 MachinePointerInfo(), MachineMemOperand::MOLoad, 4, Align(4)); 3233 auto Load = B.buildLoad(V4S8, Ptr, *MMO); 3234 3235 AInfo Info(MF->getSubtarget()); 3236 DummyGISelObserver Observer; 3237 B.setInsertPt(*EntryMBB, Load->getIterator()); 3238 LegalizerHelper Helper(*MF, Info, Observer, B); 3239 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3240 Helper.bitcast(*Load, 0, S32)); 3241 3242 auto CheckStr = R"( 3243 CHECK: [[PTR:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF 3244 CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD 3245 CHECK: [[CAST:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[LOAD]] 3246 3247 )"; 3248 3249 // Check 3250 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3251 } 3252 3253 TEST_F(AArch64GISelMITest, BitcastStore) { 3254 setUp(); 3255 if (!TM) 3256 return; 3257 3258 LLT P0 = LLT::pointer(0, 64); 3259 LLT S32 = LLT::scalar(32); 3260 LLT V4S8 = LLT::vector(4, 8); 3261 auto Ptr = B.buildUndef(P0); 3262 3263 DefineLegalizerInfo(A, {}); 3264 3265 MachineMemOperand *MMO = B.getMF().getMachineMemOperand( 3266 MachinePointerInfo(), MachineMemOperand::MOStore, 4, Align(4)); 3267 auto Val = B.buildUndef(V4S8); 3268 auto Store = B.buildStore(Val, Ptr, *MMO); 3269 3270 AInfo Info(MF->getSubtarget()); 3271 DummyGISelObserver Observer; 3272 LegalizerHelper Helper(*MF, Info, Observer, B); 3273 B.setInsertPt(*EntryMBB, Store->getIterator()); 3274 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3275 Helper.bitcast(*Store, 0, S32)); 3276 3277 auto CheckStr = R"( 3278 CHECK: [[VAL:%[0-9]+]]:_(<4 x s8>) = G_IMPLICIT_DEF 3279 CHECK: [[CAST:%[0-9]+]]:_(s32) = G_BITCAST [[VAL]] 3280 CHECK: G_STORE [[CAST]] 3281 )"; 3282 3283 // Check 3284 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3285 } 3286 3287 TEST_F(AArch64GISelMITest, BitcastSelect) { 3288 setUp(); 3289 if (!TM) 3290 return; 3291 3292 LLT S1 = LLT::scalar(1); 3293 LLT S32 = LLT::scalar(32); 3294 LLT V4S8 = LLT::vector(4, 8); 3295 3296 DefineLegalizerInfo(A, {}); 3297 3298 auto Cond = B.buildUndef(S1); 3299 auto Val0 = B.buildConstant(V4S8, 123); 3300 auto Val1 = B.buildConstant(V4S8, 99); 3301 3302 auto Select = B.buildSelect(V4S8, Cond, Val0, Val1); 3303 3304 AInfo Info(MF->getSubtarget()); 3305 DummyGISelObserver Observer; 3306 LegalizerHelper Helper(*MF, Info, Observer, B); 3307 B.setInsertPt(*EntryMBB, Select->getIterator()); 3308 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3309 Helper.bitcast(*Select, 0, S32)); 3310 3311 auto CheckStr = R"( 3312 CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR 3313 CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR 3314 CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]] 3315 CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]] 3316 CHECK: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT %{{[0-9]+}}:_(s1), [[CAST0]]:_, [[CAST1]]:_ 3317 CHECK: [[CAST2:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[SELECT]] 3318 )"; 3319 3320 // Check 3321 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3322 3323 // Doesn't make sense 3324 auto VCond = B.buildUndef(LLT::vector(4, 1)); 3325 auto VSelect = B.buildSelect(V4S8, VCond, Val0, Val1); 3326 3327 B.setInsertPt(*EntryMBB, VSelect->getIterator()); 3328 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize, 3329 Helper.bitcast(*VSelect, 0, S32)); 3330 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize, 3331 Helper.bitcast(*VSelect, 1, LLT::scalar(4))); 3332 } 3333 3334 TEST_F(AArch64GISelMITest, BitcastBitOps) { 3335 setUp(); 3336 if (!TM) 3337 return; 3338 3339 LLT S32 = LLT::scalar(32); 3340 LLT V4S8 = LLT::vector(4, 8); 3341 3342 DefineLegalizerInfo(A, {}); 3343 3344 auto Val0 = B.buildConstant(V4S8, 123); 3345 auto Val1 = B.buildConstant(V4S8, 99); 3346 auto And = B.buildAnd(V4S8, Val0, Val1); 3347 auto Or = B.buildOr(V4S8, Val0, Val1); 3348 auto Xor = B.buildXor(V4S8, Val0, Val1); 3349 3350 AInfo Info(MF->getSubtarget()); 3351 DummyGISelObserver Observer; 3352 LegalizerHelper Helper(*MF, Info, Observer, B); 3353 B.setInsertPt(*EntryMBB, And->getIterator()); 3354 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3355 Helper.bitcast(*And, 0, S32)); 3356 3357 B.setInsertPt(*EntryMBB, Or->getIterator()); 3358 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3359 Helper.bitcast(*Or, 0, S32)); 3360 3361 B.setInsertPt(*EntryMBB, Xor->getIterator()); 3362 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3363 Helper.bitcast(*Xor, 0, S32)); 3364 3365 auto CheckStr = R"( 3366 CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR 3367 CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR 3368 CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]] 3369 CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]] 3370 CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[CAST0]]:_, [[CAST1]]:_ 3371 CHECK: [[CAST_AND:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[AND]] 3372 CHECK: [[CAST2:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]] 3373 CHECK: [[CAST3:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]] 3374 CHECK: [[OR:%[0-9]+]]:_(s32) = G_OR [[CAST2]]:_, [[CAST3]]:_ 3375 CHECK: [[CAST_OR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[OR]] 3376 CHECK: [[CAST4:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]] 3377 CHECK: [[CAST5:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]] 3378 CHECK: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[CAST4]]:_, [[CAST5]]:_ 3379 CHECK: [[CAST_XOR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[XOR]] 3380 )"; 3381 3382 // Check 3383 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3384 } 3385 3386 TEST_F(AArch64GISelMITest, CreateLibcall) { 3387 setUp(); 3388 if (!TM) 3389 return; 3390 3391 DefineLegalizerInfo(A, {}); 3392 3393 AInfo Info(MF->getSubtarget()); 3394 DummyGISelObserver Observer; 3395 3396 LLVMContext &Ctx = MF->getFunction().getContext(); 3397 auto *RetTy = Type::getVoidTy(Ctx); 3398 3399 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3400 createLibcall(B, "abort", {{}, RetTy}, {}, CallingConv::C)); 3401 3402 auto CheckStr = R"( 3403 CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp 3404 CHECK: BL &abort 3405 CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp 3406 )"; 3407 3408 // Check 3409 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3410 } 3411 3412 // Test narrowing of G_IMPLICIT_DEF 3413 TEST_F(AArch64GISelMITest, NarrowImplicitDef) { 3414 setUp(); 3415 if (!TM) 3416 return; 3417 3418 DefineLegalizerInfo(A, {}); 3419 3420 // Make sure that G_IMPLICIT_DEF can be narrowed if the original size is not a 3421 // multiple of narrow size 3422 LLT S32{LLT::scalar(32)}; 3423 LLT S48{LLT::scalar(48)}; 3424 LLT S64{LLT::scalar(64)}; 3425 LLT V2S64{{LLT::vector(2, 64)}}; 3426 3427 auto Implicit1 = B.buildUndef(S64); 3428 auto Implicit2 = B.buildUndef(S64); 3429 auto Implicit3 = B.buildUndef(V2S64); 3430 auto Implicit4 = B.buildUndef(V2S64); 3431 3432 AInfo Info(MF->getSubtarget()); 3433 DummyGISelObserver Observer; 3434 LegalizerHelper Helper(*MF, Info, Observer, B); 3435 3436 // Perform Legalization 3437 3438 B.setInsertPt(*EntryMBB, Implicit1->getIterator()); 3439 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3440 Helper.narrowScalar(*Implicit1, 0, S48)); 3441 3442 B.setInsertPt(*EntryMBB, Implicit2->getIterator()); 3443 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3444 Helper.narrowScalar(*Implicit2, 0, S32)); 3445 3446 B.setInsertPt(*EntryMBB, Implicit3->getIterator()); 3447 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3448 Helper.narrowScalar(*Implicit3, 0, S48)); 3449 3450 B.setInsertPt(*EntryMBB, Implicit4->getIterator()); 3451 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3452 Helper.narrowScalar(*Implicit4, 0, S32)); 3453 3454 const auto *CheckStr = R"( 3455 CHECK: [[DEF:%[0-9]+]]:_(s48) = G_IMPLICIT_DEF 3456 CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[DEF]] 3457 3458 CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 3459 CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 3460 CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]]:_(s32), [[DEF1]] 3461 3462 CHECK: [[DEF:%[0-9]+]]:_(<2 x s48>) = G_IMPLICIT_DEF 3463 CHECK: [[ANYEXT:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[DEF]] 3464 3465 CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 3466 CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 3467 CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 3468 CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 3469 CHECK: [[BV:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[DEF]]:_(s32), [[DEF1]]:_(s32), [[DEF2]]:_(s32), [[DEF3]]:_(s32) 3470 )"; 3471 3472 // Check 3473 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3474 } 3475 3476 // Test widening of G_FREEZE 3477 TEST_F(AArch64GISelMITest, WidenFreeze) { 3478 setUp(); 3479 if (!TM) 3480 return; 3481 3482 DefineLegalizerInfo(A, {}); 3483 3484 // Make sure that G_FREEZE is widened with anyext 3485 LLT S64{LLT::scalar(64)}; 3486 LLT S128{LLT::scalar(128)}; 3487 LLT V2S32{LLT::vector(2, 32)}; 3488 LLT V2S64{LLT::vector(2, 64)}; 3489 3490 auto Vector = B.buildBitcast(V2S32, Copies[0]); 3491 3492 auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]}); 3493 auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector}); 3494 3495 AInfo Info(MF->getSubtarget()); 3496 DummyGISelObserver Observer; 3497 LegalizerHelper Helper(*MF, Info, Observer, B); 3498 3499 // Perform Legalization 3500 3501 B.setInsertPt(*EntryMBB, FreezeScalar->getIterator()); 3502 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3503 Helper.widenScalar(*FreezeScalar, 0, S128)); 3504 3505 B.setInsertPt(*EntryMBB, FreezeVector->getIterator()); 3506 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3507 Helper.widenScalar(*FreezeVector, 0, V2S64)); 3508 3509 const auto *CheckStr = R"( 3510 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 3511 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]] 3512 3513 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[COPY]] 3514 CHECK: [[FREEZE:%[0-9]+]]:_(s128) = G_FREEZE [[ANYEXT]] 3515 CHECK: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[FREEZE]] 3516 3517 CHECK: [[ANYEXT1:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[BITCAST]] 3518 CHECK: [[FREEZE1:%[0-9]+]]:_(<2 x s64>) = G_FREEZE [[ANYEXT1]] 3519 CHECK: [[TRUNC1:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[FREEZE1]] 3520 )"; 3521 3522 // Check 3523 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3524 } 3525 3526 // Test narrowing of G_FREEZE 3527 TEST_F(AArch64GISelMITest, NarrowFreeze) { 3528 setUp(); 3529 if (!TM) 3530 return; 3531 3532 DefineLegalizerInfo(A, {}); 3533 3534 // Make sure that G_FREEZE is narrowed using unmerge/extract 3535 LLT S16{LLT::scalar(16)}; 3536 LLT S32{LLT::scalar(32)}; 3537 LLT S33{LLT::scalar(33)}; 3538 LLT S64{LLT::scalar(64)}; 3539 LLT V2S16{LLT::vector(2, 16)}; 3540 LLT V2S32{LLT::vector(2, 32)}; 3541 3542 auto Trunc = B.buildTrunc(S33, {Copies[0]}); 3543 auto Vector = B.buildBitcast(V2S32, Copies[0]); 3544 3545 auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]}); 3546 auto FreezeOdd = B.buildInstr(TargetOpcode::G_FREEZE, {S33}, {Trunc}); 3547 auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector}); 3548 auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector}); 3549 3550 AInfo Info(MF->getSubtarget()); 3551 DummyGISelObserver Observer; 3552 LegalizerHelper Helper(*MF, Info, Observer, B); 3553 3554 // Perform Legalization 3555 3556 B.setInsertPt(*EntryMBB, FreezeScalar->getIterator()); 3557 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3558 Helper.narrowScalar(*FreezeScalar, 0, S32)); 3559 3560 B.setInsertPt(*EntryMBB, FreezeOdd->getIterator()); 3561 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3562 Helper.narrowScalar(*FreezeOdd, 0, S32)); 3563 3564 B.setInsertPt(*EntryMBB, FreezeVector->getIterator()); 3565 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3566 Helper.narrowScalar(*FreezeVector, 0, V2S16)); 3567 3568 B.setInsertPt(*EntryMBB, FreezeVector1->getIterator()); 3569 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3570 Helper.narrowScalar(*FreezeVector1, 0, S16)); 3571 3572 const auto *CheckStr = R"( 3573 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 3574 CHECK: [[TRUNC:%[0-9]+]]:_(s33) = G_TRUNC [[COPY]] 3575 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]] 3576 3577 CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]] 3578 CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]] 3579 CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]] 3580 CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE]]:_(s32), [[FREEZE1]] 3581 3582 CHECK: (s1) = G_UNMERGE_VALUES [[TRUNC]]:_(s33) 3583 CHECK: [[UNDEF:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF 3584 CHECK: [[MV1:%[0-9]+]]:_(s32) = G_MERGE_VALUES 3585 CHECK: [[MV2:%[0-9]+]]:_(s32) = G_MERGE_VALUES 3586 CHECK: [[UNDEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 3587 CHECK: [[FREEZE2:%[0-9]+]]:_(s32) = G_FREEZE [[MV1]] 3588 CHECK: [[FREEZE3:%[0-9]+]]:_(s32) = G_FREEZE [[MV2]] 3589 CHECK: [[UNDEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 3590 CHECK: [[MV3:%[0-9]+]]:_(s1056) = G_MERGE_VALUES [[FREEZE2]]:_(s32), [[FREEZE3]]:_(s32), [[UNDEF2]] 3591 CHECK: [[TRUNC1:%[0-9]+]]:_(s33) = G_TRUNC [[MV3]] 3592 3593 CHECK: [[BITCAST1:%[0-9]+]]:_(s64) = G_BITCAST [[BITCAST]] 3594 CHECK: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST1]] 3595 CHECK: [[FREEZE4:%[0-9]+]]:_(s32) = G_FREEZE [[UV2]] 3596 CHECK: [[FREEZE5:%[0-9]+]]:_(s32) = G_FREEZE [[UV3]] 3597 CHECK: [[MV4:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE4]]:_(s32), [[FREEZE5]]:_(s32) 3598 CHECK: [[BITCAST2:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[MV4]] 3599 3600 CHECK: [[BITCAST3:%[0-9]+]]:_(s64) = G_BITCAST [[BITCAST]] 3601 CHECK: [[UV4:%[0-9]+]]:_(s16), [[UV5:%[0-9]+]]:_(s16), [[UV6:%[0-9]+]]:_(s16), [[UV7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST3]] 3602 CHECK: [[FREEZE6:%[0-9]+]]:_(s16) = G_FREEZE [[UV4]] 3603 CHECK: [[FREEZE7:%[0-9]+]]:_(s16) = G_FREEZE [[UV5]] 3604 CHECK: [[FREEZE8:%[0-9]+]]:_(s16) = G_FREEZE [[UV6]] 3605 CHECK: [[FREEZE9:%[0-9]+]]:_(s16) = G_FREEZE [[UV7]] 3606 CHECK: [[MV5:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE6]]:_(s16), [[FREEZE7]]:_(s16), [[FREEZE8]]:_(s16), [[FREEZE9]] 3607 CHECK: [[BITCAST3:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[MV5]] 3608 )"; 3609 3610 // Check 3611 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3612 } 3613 3614 // Test fewer elements of G_FREEZE 3615 TEST_F(AArch64GISelMITest, FewerElementsFreeze) { 3616 setUp(); 3617 if (!TM) 3618 return; 3619 3620 DefineLegalizerInfo(A, {}); 3621 3622 LLT S32{LLT::scalar(32)}; 3623 LLT V2S16{LLT::vector(2, 16)}; 3624 LLT V2S32{LLT::vector(2, 32)}; 3625 LLT V4S16{LLT::vector(4, 16)}; 3626 3627 auto Vector1 = B.buildBitcast(V2S32, Copies[0]); 3628 auto Vector2 = B.buildBitcast(V4S16, Copies[0]); 3629 3630 auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1}); 3631 auto FreezeVector2 = B.buildInstr(TargetOpcode::G_FREEZE, {V4S16}, {Vector2}); 3632 3633 AInfo Info(MF->getSubtarget()); 3634 DummyGISelObserver Observer; 3635 LegalizerHelper Helper(*MF, Info, Observer, B); 3636 3637 // Perform Legalization 3638 3639 B.setInsertPt(*EntryMBB, FreezeVector1->getIterator()); 3640 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3641 Helper.fewerElementsVector(*FreezeVector1, 0, S32)); 3642 3643 B.setInsertPt(*EntryMBB, FreezeVector2->getIterator()); 3644 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3645 Helper.fewerElementsVector(*FreezeVector2, 0, V2S16)); 3646 3647 const auto *CheckStr = R"( 3648 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 3649 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]] 3650 CHECK: [[BITCAST1:%[0-9]+]]:_(<4 x s16>) = G_BITCAST [[COPY]] 3651 3652 CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]] 3653 CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]] 3654 CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]] 3655 CHECK: [[MV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FREEZE]]:_(s32), [[FREEZE1]] 3656 3657 CHECK: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[BITCAST1]] 3658 CHECK: [[FREEZE2:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV]] 3659 CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV1]] 3660 CHECK: [[MV:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[FREEZE2]]:_(<2 x s16>), [[FREEZE3]] 3661 )"; 3662 3663 // Check 3664 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3665 } 3666 3667 // Test more elements of G_FREEZE 3668 TEST_F(AArch64GISelMITest, MoreElementsFreeze) { 3669 setUp(); 3670 if (!TM) 3671 return; 3672 3673 DefineLegalizerInfo(A, {}); 3674 3675 LLT V2S32{LLT::vector(2, 32)}; 3676 LLT V4S32{LLT::vector(4, 32)}; 3677 3678 auto Vector1 = B.buildBitcast(V2S32, Copies[0]); 3679 auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1}); 3680 3681 AInfo Info(MF->getSubtarget()); 3682 DummyGISelObserver Observer; 3683 LegalizerHelper Helper(*MF, Info, Observer, B); 3684 3685 // Perform Legalization 3686 B.setInsertPt(*EntryMBB, FreezeVector1->getIterator()); 3687 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3688 Helper.moreElementsVector(*FreezeVector1, 0, V4S32)); 3689 3690 const auto *CheckStr = R"( 3691 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY 3692 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]] 3693 CHECK: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 3694 CHECK: [[CV:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[BITCAST]]:_(<2 x s32>), [[UNDEF]] 3695 CHECK: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE [[CV]] 3696 CHECK: [[EXTR0:%[0-9]+]]:_(<2 x s32>), [[EXTR1:%[0-9]+]]:_(<2 x s32>) = G_UNMERGE_VALUES [[FREEZE]]:_(<4 x s32>) 3697 )"; 3698 3699 // Check 3700 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3701 } 3702 3703 // Test fewer elements of G_INSERT_VECTOR_ELEMENT 3704 TEST_F(AArch64GISelMITest, FewerElementsInsertVectorElt) { 3705 setUp(); 3706 if (!TM) 3707 return; 3708 3709 DefineLegalizerInfo(A, {}); 3710 3711 LLT P0{LLT::pointer(0, 64)}; 3712 LLT S64{LLT::scalar(64)}; 3713 LLT S16{LLT::scalar(16)}; 3714 LLT V2S16{LLT::vector(2, 16)}; 3715 LLT V3S16{LLT::vector(3, 16)}; 3716 LLT V8S16{LLT::vector(8, 16)}; 3717 3718 auto Ptr0 = B.buildIntToPtr(P0, Copies[0]); 3719 auto VectorV8 = B.buildLoad(V8S16, Ptr0, MachinePointerInfo(), Align(8)); 3720 auto Value = B.buildTrunc(S16, Copies[1]); 3721 3722 auto Seven = B.buildConstant(S64, 7); 3723 auto InsertV8Constant7_0 = 3724 B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven); 3725 auto InsertV8Constant7_1 = 3726 B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven); 3727 3728 B.buildStore(InsertV8Constant7_0, Ptr0, MachinePointerInfo(), Align(8), 3729 MachineMemOperand::MOVolatile); 3730 B.buildStore(InsertV8Constant7_1, Ptr0, MachinePointerInfo(), Align(8), 3731 MachineMemOperand::MOVolatile); 3732 3733 AInfo Info(MF->getSubtarget()); 3734 DummyGISelObserver Observer; 3735 LegalizerHelper Helper(*MF, Info, Observer, B); 3736 3737 // Perform Legalization 3738 B.setInsertPt(*EntryMBB, InsertV8Constant7_0->getIterator()); 3739 3740 // This should index the high element of the 4th piece of an unmerge. 3741 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3742 Helper.fewerElementsVector(*InsertV8Constant7_0, 0, V2S16)); 3743 3744 // This case requires extracting an intermediate vector type into the target 3745 // v4s16. 3746 B.setInsertPt(*EntryMBB, InsertV8Constant7_1->getIterator()); 3747 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3748 Helper.fewerElementsVector(*InsertV8Constant7_1, 0, V3S16)); 3749 3750 const auto *CheckStr = R"( 3751 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY 3752 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY 3753 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY 3754 CHECK: [[PTR0:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY0]] 3755 CHECK: [[VEC8:%[0-9]+]]:_(<8 x s16>) = G_LOAD [[PTR0]]:_(p0) :: (load 16, align 8) 3756 CHECK: [[INSERT_VAL:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]] 3757 3758 3759 CHECK: [[UNMERGE0:%[0-9]+]]:_(<2 x s16>), [[UNMERGE1:%[0-9]+]]:_(<2 x s16>), [[UNMERGE2:%[0-9]+]]:_(<2 x s16>), [[UNMERGE3:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[VEC8]] 3760 CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 3761 CHECK: [[SUB_INSERT_7:%[0-9]+]]:_(<2 x s16>) = G_INSERT_VECTOR_ELT [[UNMERGE3]]:_, [[INSERT_VAL]]:_(s16), [[ONE]] 3762 CHECK: [[INSERT_V8_7_0:%[0-9]+]]:_(<8 x s16>) = G_CONCAT_VECTORS [[UNMERGE0]]:_(<2 x s16>), [[UNMERGE1]]:_(<2 x s16>), [[UNMERGE2]]:_(<2 x s16>), [[SUB_INSERT_7]]:_(<2 x s16>) 3763 3764 3765 CHECK: [[UNMERGE1_0:%[0-9]+]]:_(s16), [[UNMERGE1_1:%[0-9]+]]:_(s16), [[UNMERGE1_2:%[0-9]+]]:_(s16), [[UNMERGE1_3:%[0-9]+]]:_(s16), [[UNMERGE1_4:%[0-9]+]]:_(s16), [[UNMERGE1_5:%[0-9]+]]:_(s16), [[UNMERGE1_6:%[0-9]+]]:_(s16), [[UNMERGE1_7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[VEC8]]:_(<8 x s16>) 3766 CHECK: [[IMPDEF_S16:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF 3767 CHECK: [[BUILD0:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_0]]:_(s16), [[UNMERGE1_1]]:_(s16), [[UNMERGE1_2]]:_(s16) 3768 CHECK: [[BUILD1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_3]]:_(s16), [[UNMERGE1_4]]:_(s16), [[UNMERGE1_5]]:_(s16) 3769 CHECK: [[BUILD2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_6]]:_(s16), [[UNMERGE1_7]]:_(s16), [[IMPDEF_S16]]:_(s16) 3770 CHECK: [[IMPDEF_V3S16:%[0-9]+]]:_(<3 x s16>) = G_IMPLICIT_DEF 3771 CHECK: [[ONE_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 3772 CHECK: [[SUB_INSERT_7_V3S16:%[0-9]+]]:_(<3 x s16>) = G_INSERT_VECTOR_ELT [[BUILD2]]:_, [[INSERT_VAL]]:_(s16), [[ONE_1]] 3773 3774 CHECK: [[WIDE_CONCAT_DEAD:%[0-9]+]]:_(<24 x s16>) = G_CONCAT_VECTORS [[BUILD0]]:_(<3 x s16>), [[BUILD1]]:_(<3 x s16>), [[SUB_INSERT_7_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>) 3775 CHECK: [[WIDE_CONCAT:%[0-9]+]]:_(<24 x s16>) = G_CONCAT_VECTORS [[BUILD0]]:_(<3 x s16>), [[BUILD1]]:_(<3 x s16>), [[SUB_INSERT_7_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>) 3776 CHECK: [[INSERT_V8_7_1:%[0-9]+]]:_(<8 x s16>), %{{[0-9]+}}:_(<8 x s16>), %{{[0-9]+}}:_(<8 x s16>) = G_UNMERGE_VALUES [[WIDE_CONCAT]]:_(<24 x s16>) 3777 3778 3779 CHECK: G_STORE [[INSERT_V8_7_0]] 3780 CHECK: G_STORE [[INSERT_V8_7_1]] 3781 )"; 3782 3783 // Check 3784 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3785 } 3786 3787 // Test widen scalar of G_UNMERGE_VALUES 3788 TEST_F(AArch64GISelMITest, widenScalarUnmerge) { 3789 setUp(); 3790 if (!TM) 3791 return; 3792 3793 DefineLegalizerInfo(A, {}); 3794 3795 LLT S96{LLT::scalar(96)}; 3796 LLT S64{LLT::scalar(64)}; 3797 LLT S48{LLT::scalar(48)}; 3798 3799 auto Src = B.buildAnyExt(S96, Copies[0]); 3800 auto Unmerge = B.buildUnmerge(S48, Src); 3801 3802 AInfo Info(MF->getSubtarget()); 3803 DummyGISelObserver Observer; 3804 LegalizerHelper Helper(*MF, Info, Observer, B); 3805 3806 // Perform Legalization 3807 B.setInsertPt(*EntryMBB, Unmerge->getIterator()); 3808 3809 // This should create unmerges to a GCD type (S16), then remerge to S48 3810 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, 3811 Helper.widenScalar(*Unmerge, 0, S64)); 3812 3813 const auto *CheckStr = R"( 3814 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY 3815 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY 3816 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY 3817 CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY0]] 3818 CHECK: [[ANYEXT1:%[0-9]+]]:_(s192) = G_ANYEXT [[ANYEXT]] 3819 CHECK: [[UNMERGE:%[0-9]+]]:_(s64), [[UNMERGE1:%[0-9]+]]:_(s64), [[UNMERGE2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT1]] 3820 CHECK: [[UNMERGE3:%[0-9]+]]:_(s16), [[UNMERGE4:%[0-9]+]]:_(s16), [[UNMERGE5:%[0-9]+]]:_(s16), [[UNMERGE6:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE]] 3821 CHECK: [[UNMERGE7:%[0-9]+]]:_(s16), [[UNMERGE8:%[0-9]+]]:_(s16), [[UNMERGE9:%[0-9]+]]:_(s16), [[UNMERGE10:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE1]] 3822 CHECK: [[UNMERGE11:%[0-9]+]]:_(s16), [[UNMERGE12:%[0-9]+]]:_(s16), [[UNMERGE13:%[0-9]+]]:_(s16), [[UNMERGE14:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE2]] 3823 CHECK: [[MERGE:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE3]]:_(s16), [[UNMERGE4]]:_(s16), [[UNMERGE5]]:_(s16) 3824 CHECK: [[MERGE1:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE6]]:_(s16), [[UNMERGE7]]:_(s16), [[UNMERGE8]]:_(s16) 3825 )"; 3826 3827 // Check 3828 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 3829 } 3830 3831 } // namespace 3832