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