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