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