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 namespace { 13 14 class DummyGISelObserver : public GISelChangeObserver { 15 public: 16 void changingInstr(MachineInstr &MI) override {} 17 void changedInstr(MachineInstr &MI) override {} 18 void createdInstr(MachineInstr &MI) override {} 19 void erasingInstr(MachineInstr &MI) override {} 20 }; 21 22 // Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom, 23 // in which case it becomes CTTZ_ZERO_UNDEF with select. 24 TEST_F(GISelMITest, LowerBitCountingCTTZ0) { 25 if (!TM) 26 return; 27 28 // Declare your legalization info 29 DefineLegalizerInfo(A, { 30 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s64, s64}}); 31 }); 32 // Build Instr 33 auto MIBCTTZ = 34 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]}); 35 AInfo Info(MF->getSubtarget()); 36 DummyGISelObserver Observer; 37 LegalizerHelper Helper(*MF, Info, Observer, B); 38 // Perform Legalization 39 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == 40 LegalizerHelper::LegalizeResult::Legalized); 41 42 auto CheckStr = R"( 43 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF %0 44 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 45 CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64 46 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]] 47 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]] 48 )"; 49 50 // Check 51 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 52 } 53 54 // CTTZ expansion in terms of CTLZ 55 TEST_F(GISelMITest, LowerBitCountingCTTZ1) { 56 if (!TM) 57 return; 58 59 // Declare your legalization info 60 DefineLegalizerInfo(A, { 61 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s64, s64}}); 62 }); 63 // Build Instr 64 auto MIBCTTZ = 65 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]}); 66 AInfo Info(MF->getSubtarget()); 67 DummyGISelObserver Observer; 68 LegalizerHelper Helper(*MF, Info, Observer, B); 69 // Perform Legalization 70 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == 71 LegalizerHelper::LegalizeResult::Legalized); 72 73 auto CheckStr = R"( 74 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1 75 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]] 76 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]] 77 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_ 78 CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64 79 CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_ 80 CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_ 81 )"; 82 83 // Check 84 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 85 } 86 87 // CTTZ expansion in terms of CTPOP 88 TEST_F(GISelMITest, LowerBitCountingCTTZ2) { 89 if (!TM) 90 return; 91 92 // Declare your legalization info 93 DefineLegalizerInfo(A, { 94 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s64, s64}}); 95 }); 96 // Build 97 auto MIBCTTZ = 98 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]}); 99 AInfo Info(MF->getSubtarget()); 100 DummyGISelObserver Observer; 101 LegalizerHelper Helper(*MF, Info, Observer, B); 102 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == 103 LegalizerHelper::LegalizeResult::Legalized); 104 105 auto CheckStr = R"( 106 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1 107 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]] 108 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]] 109 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_ 110 CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]] 111 )"; 112 113 // Check 114 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 115 } 116 117 // CTTZ_ZERO_UNDEF expansion in terms of CTTZ 118 TEST_F(GISelMITest, LowerBitCountingCTTZ3) { 119 if (!TM) 120 return; 121 122 // Declare your legalization info 123 DefineLegalizerInfo(A, { 124 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s64, s64}}); 125 }); 126 // Build 127 auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, 128 {LLT::scalar(64)}, {Copies[0]}); 129 AInfo Info(MF->getSubtarget()); 130 DummyGISelObserver Observer; 131 LegalizerHelper Helper(*MF, Info, Observer, B); 132 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == 133 LegalizerHelper::LegalizeResult::Legalized); 134 135 auto CheckStr = R"( 136 CHECK: CTTZ 137 )"; 138 139 // Check 140 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 141 } 142 143 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF 144 TEST_F(GISelMITest, LowerBitCountingCTLZ0) { 145 if (!TM) 146 return; 147 148 // Declare your legalization info 149 DefineLegalizerInfo(A, { 150 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s64, s64}}); 151 }); 152 // Build 153 auto MIBCTLZ = 154 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]}); 155 AInfo Info(MF->getSubtarget()); 156 DummyGISelObserver Observer; 157 LegalizerHelper Helper(*MF, Info, Observer, B); 158 EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) == 159 LegalizerHelper::LegalizeResult::Legalized); 160 161 auto CheckStr = R"( 162 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0 163 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 164 CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64 165 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]] 166 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]] 167 )"; 168 169 // Check 170 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 171 } 172 173 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall 174 TEST_F(GISelMITest, LowerBitCountingCTLZLibcall) { 175 if (!TM) 176 return; 177 178 // Declare your legalization info 179 DefineLegalizerInfo(A, { 180 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({{s64, s64}}); 181 }); 182 // Build 183 auto MIBCTLZ = 184 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]}); 185 AInfo Info(MF->getSubtarget()); 186 DummyGISelObserver Observer; 187 LegalizerHelper Helper(*MF, Info, Observer, B); 188 EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) == 189 LegalizerHelper::LegalizeResult::Legalized); 190 191 auto CheckStr = R"( 192 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0 193 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 194 CHECK: [[THIRTY2:%[0-9]+]]:_(s64) = G_CONSTANT i64 64 195 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]] 196 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[THIRTY2]]:_, [[CZU]] 197 )"; 198 199 // Check 200 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 201 } 202 203 // CTLZ expansion 204 TEST_F(GISelMITest, LowerBitCountingCTLZ1) { 205 if (!TM) 206 return; 207 208 // Declare your legalization info 209 DefineLegalizerInfo(A, { 210 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s8, s8}}); 211 }); 212 // Build 213 // Trunc it to s8. 214 LLT s8{LLT::scalar(8)}; 215 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 216 auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc}); 217 AInfo Info(MF->getSubtarget()); 218 DummyGISelObserver Observer; 219 LegalizerHelper Helper(*MF, Info, Observer, B); 220 EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) == 221 LegalizerHelper::LegalizeResult::Legalized); 222 223 auto CheckStr = R"( 224 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 225 CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1 226 CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_ 227 CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_ 228 CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2 229 CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_ 230 CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_ 231 CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4 232 CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_ 233 CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_ 234 CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_ 235 CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8 236 CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_ 237 )"; 238 239 // Check 240 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 241 } 242 243 // CTLZ widening. 244 TEST_F(GISelMITest, WidenBitCountingCTLZ) { 245 if (!TM) 246 return; 247 248 // Declare your legalization info 249 DefineLegalizerInfo(A, { 250 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s16, s16}}); 251 }); 252 // Build 253 // Trunc it to s8. 254 LLT s8{LLT::scalar(8)}; 255 LLT s16{LLT::scalar(16)}; 256 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 257 auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc}); 258 AInfo Info(MF->getSubtarget()); 259 DummyGISelObserver Observer; 260 LegalizerHelper Helper(*MF, Info, Observer, B); 261 EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ, 1, s16) == 262 LegalizerHelper::LegalizeResult::Legalized); 263 264 auto CheckStr = R"( 265 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 266 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 267 CHECK: [[Ctlz:%[0-9]+]]:_(s16) = G_CTLZ [[Zext]] 268 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8 269 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[Ctlz]]:_, [[Cst8]]:_ 270 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]] 271 )"; 272 273 // Check 274 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 275 } 276 277 // CTLZ_ZERO_UNDEF widening. 278 TEST_F(GISelMITest, WidenBitCountingCTLZZeroUndef) { 279 if (!TM) 280 return; 281 282 // Declare your legalization info 283 DefineLegalizerInfo(A, { 284 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s16, s16}}); 285 }); 286 // Build 287 // Trunc it to s8. 288 LLT s8{LLT::scalar(8)}; 289 LLT s16{LLT::scalar(16)}; 290 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 291 auto MIBCTLZ_ZU = 292 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {s8}, {MIBTrunc}); 293 AInfo Info(MF->getSubtarget()); 294 DummyGISelObserver Observer; 295 LegalizerHelper Helper(*MF, Info, Observer, B); 296 EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 1, s16) == 297 LegalizerHelper::LegalizeResult::Legalized); 298 299 auto CheckStr = R"( 300 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 301 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 302 CHECK: [[CtlzZu:%[0-9]+]]:_(s16) = G_CTLZ_ZERO_UNDEF [[Zext]] 303 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8 304 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[CtlzZu]]:_, [[Cst8]]:_ 305 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]] 306 )"; 307 308 // Check 309 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 310 } 311 312 // CTPOP widening. 313 TEST_F(GISelMITest, WidenBitCountingCTPOP) { 314 if (!TM) 315 return; 316 317 // Declare your legalization info 318 DefineLegalizerInfo(A, { 319 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}}); 320 }); 321 // Build 322 // Trunc it to s8. 323 LLT s8{LLT::scalar(8)}; 324 LLT s16{LLT::scalar(16)}; 325 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 326 auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s8}, {MIBTrunc}); 327 AInfo Info(MF->getSubtarget()); 328 DummyGISelObserver Observer; 329 LegalizerHelper Helper(*MF, Info, Observer, B); 330 EXPECT_TRUE(Helper.widenScalar(*MIBCTPOP, 1, s16) == 331 LegalizerHelper::LegalizeResult::Legalized); 332 333 auto CheckStr = R"( 334 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 335 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 336 CHECK: [[Ctpop:%[0-9]+]]:_(s16) = G_CTPOP [[Zext]] 337 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Ctpop]] 338 )"; 339 340 // Check 341 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 342 } 343 344 // CTTZ_ZERO_UNDEF widening. 345 TEST_F(GISelMITest, WidenBitCountingCTTZ_ZERO_UNDEF) { 346 if (!TM) 347 return; 348 349 // Declare your legalization info 350 DefineLegalizerInfo(A, { 351 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s16, s16}}); 352 }); 353 // Build 354 // Trunc it to s8. 355 LLT s8{LLT::scalar(8)}; 356 LLT s16{LLT::scalar(16)}; 357 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 358 auto MIBCTTZ_ZERO_UNDEF = 359 B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {s8}, {MIBTrunc}); 360 AInfo Info(MF->getSubtarget()); 361 DummyGISelObserver Observer; 362 LegalizerHelper Helper(*MF, Info, Observer, B); 363 EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 1, s16) == 364 LegalizerHelper::LegalizeResult::Legalized); 365 366 auto CheckStr = R"( 367 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 368 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 369 CHECK: [[CttzZu:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[Zext]] 370 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CttzZu]] 371 )"; 372 373 // Check 374 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 375 } 376 377 // CTTZ widening. 378 TEST_F(GISelMITest, WidenBitCountingCTTZ) { 379 if (!TM) 380 return; 381 382 // Declare your legalization info 383 DefineLegalizerInfo(A, { 384 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s16, s16}}); 385 }); 386 // Build 387 // Trunc it to s8. 388 LLT s8{LLT::scalar(8)}; 389 LLT s16{LLT::scalar(16)}; 390 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 391 auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, {s8}, {MIBTrunc}); 392 AInfo Info(MF->getSubtarget()); 393 DummyGISelObserver Observer; 394 LegalizerHelper Helper(*MF, Info, Observer, B); 395 EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ, 1, s16) == 396 LegalizerHelper::LegalizeResult::Legalized); 397 398 auto CheckStr = R"( 399 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 400 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 401 CHECK: [[Cst:%[0-9]+]]:_(s16) = G_CONSTANT i16 256 402 CHECK: [[Or:%[0-9]+]]:_(s16) = G_OR [[Zext]]:_, [[Cst]] 403 CHECK: [[Cttz:%[0-9]+]]:_(s16) = G_CTTZ [[Or]] 404 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Cttz]] 405 )"; 406 407 // Check 408 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 409 } 410 // UADDO widening. 411 TEST_F(GISelMITest, WidenUADDO) { 412 if (!TM) 413 return; 414 415 // Declare your legalization info 416 DefineLegalizerInfo(A, { 417 getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}}); 418 }); 419 // Build 420 // Trunc it to s8. 421 LLT s8{LLT::scalar(8)}; 422 LLT s16{LLT::scalar(16)}; 423 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 424 unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 425 auto MIBUAddO = 426 B.buildInstr(TargetOpcode::G_UADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc}); 427 AInfo Info(MF->getSubtarget()); 428 DummyGISelObserver Observer; 429 LegalizerHelper Helper(*MF, Info, Observer, B); 430 EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) == 431 LegalizerHelper::LegalizeResult::Legalized); 432 433 auto CheckStr = R"( 434 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 435 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 436 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 437 CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_ 438 CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255 439 CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[ADD]]:_, [[CST]]:_ 440 CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[AND]]:_ 441 CHECK: G_TRUNC [[ADD]] 442 )"; 443 444 // Check 445 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 446 } 447 448 // USUBO widening. 449 TEST_F(GISelMITest, WidenUSUBO) { 450 if (!TM) 451 return; 452 453 // Declare your legalization info 454 DefineLegalizerInfo(A, { 455 getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}}); 456 }); 457 // Build 458 // Trunc it to s8. 459 LLT s8{LLT::scalar(8)}; 460 LLT s16{LLT::scalar(16)}; 461 auto MIBTrunc = B.buildTrunc(s8, Copies[0]); 462 unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1)); 463 auto MIBUSUBO = 464 B.buildInstr(TargetOpcode::G_USUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc}); 465 AInfo Info(MF->getSubtarget()); 466 DummyGISelObserver Observer; 467 LegalizerHelper Helper(*MF, Info, Observer, B); 468 EXPECT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) == 469 LegalizerHelper::LegalizeResult::Legalized); 470 471 auto CheckStr = R"( 472 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC 473 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 474 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]] 475 CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_ 476 CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255 477 CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[SUB]]:_, [[CST]]:_ 478 CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[AND]]:_ 479 CHECK: G_TRUNC [[SUB]] 480 )"; 481 482 // Check 483 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 484 } 485 } // namespace 486