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