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