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