LLVM: lib/Transforms/InstCombine/InstCombineSelect.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

45#include

46#include

47#include

48

49#define DEBUG_TYPE "instcombine"

51

52using namespace llvm;

54

55namespace llvm {

57}

58

59

60

64

69 return nullptr;

70

71 bool IsEq;

75 IsEq = true;

77 IsEq = false;

78 else

79 return nullptr;

80

81

84 return nullptr;

85

86

87

90 if (IdC != C) {

92 return nullptr;

94 return nullptr;

95 }

96

97

100 return nullptr;

102 return nullptr;

103

104

105

110 return nullptr;

111

112

113

114

115

117}

118

119

120

121

122

123

124

125

126

127

130 bool CreateAnd,

132 const APInt *SelTC, *SelFC;

134 return nullptr;

135

137

138

139

140

141 const APInt &TC = *SelTC;

142 const APInt &FC = *SelFC;

143 if (!TC.isZero() && !FC.isZero()) {

145 return nullptr;

146

147

148 if (CreateAnd && !CondVal->hasOneUse())

149 return nullptr;

150

151

152

153

154

155 Constant *TCC = ConstantInt::get(SelType, TC);

156 Constant *FCC = ConstantInt::get(SelType, FC);

157 Constant *MaskC = ConstantInt::get(SelType, AndMask);

158 for (auto Opc : {Instruction::Or, Instruction::Xor, Instruction::Add,

159 Instruction::Sub}) {

161 FCC) {

162 if (CreateAnd)

163 V = Builder.CreateAnd(V, MaskC);

164 return Builder.CreateBinOp(Opc, TCC, V);

165 }

166 }

167

168 return nullptr;

169 }

170

171

172 if (!TC.isPowerOf2() && !FC.isPowerOf2())

173 return nullptr;

174

175

176

177 const APInt &ValC = !TC.isZero() ? TC : FC;

178 unsigned ValZeros = ValC.logBase2();

179 unsigned AndZeros = AndMask.logBase2();

180 bool ShouldNotVal = !TC.isZero();

181 bool NeedShift = ValZeros != AndZeros;

182 bool NeedZExtTrunc =

184

185

186

187

188 if (CreateAnd + ShouldNotVal + NeedShift + NeedZExtTrunc >

190 return nullptr;

191

192

193 if (CreateAnd)

194 V = Builder.CreateAnd(V, ConstantInt::get(V->getType(), AndMask));

195

196

197

198 if (ValZeros > AndZeros) {

199 V = Builder.CreateZExtOrTrunc(V, SelType);

200 V = Builder.CreateShl(V, ValZeros - AndZeros);

201 } else if (ValZeros < AndZeros) {

202 V = Builder.CreateLShr(V, AndZeros - ValZeros);

203 V = Builder.CreateZExtOrTrunc(V, SelType);

204 } else {

205 V = Builder.CreateZExtOrTrunc(V, SelType);

206 }

207

208

209

210 if (ShouldNotVal)

211 V = Builder.CreateXor(V, ValC);

212

213 return V;

214}

215

216

217

218

219

220

221

222

223

224

225

227 switch (I->getOpcode()) {

228 case Instruction::Add:

229 case Instruction::FAdd:

230 case Instruction::Mul:

231 case Instruction::FMul:

232 case Instruction::And:

233 case Instruction::Or:

234 case Instruction::Xor:

235 return 3;

236 case Instruction::Sub:

237 case Instruction::FSub:

238 case Instruction::FDiv:

239 case Instruction::Shl:

240 case Instruction::LShr:

241 case Instruction::AShr:

242 return 1;

243 default:

244 return 0;

245 }

246}

247

248

251

252

253

254

259 return nullptr;

260

261

263 Type *CondTy = Cond->getType();

267 return nullptr;

268

269

270

273 CondVTy->getElementCount() !=

275 return nullptr;

276

277

278

279

280

281

282

283

284

285 if (TI->getOpcode() != Instruction::BitCast &&

287 return nullptr;

289

290

291

292 return nullptr;

293 }

294

295

298 SI.getName() + ".v", &SI);

301 }

302

303 Value *OtherOpT, *OtherOpF;

304 bool MatchIsOpZero;

306 bool Swapped = false) -> Value * {

307 assert(!(Commute && Swapped) &&

308 "Commute and Swapped can't set at the same time");

309 if (!Swapped) {

313 MatchIsOpZero = true;

318 MatchIsOpZero = false;

320 }

321 }

322

323 if (!Commute && !Swapped)

324 return nullptr;

325

326

327

328

332 MatchIsOpZero = true;

337 MatchIsOpZero = false;

339 }

340 return nullptr;

341 };

342

344

347

348

351 FMF |= SI.getFastMathFlags();

355 NewSelI->setFastMathFlags(FMF);

356 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);

358 return NewFNeg;

359 }

360

361

362

363

364

367 if (TII && FII && TII->getIntrinsicID() == FII->getIntrinsicID()) {

369 if (Value *MatchOp = getCommonOp(TI, FI, true)) {

371 Builder.CreateSelect(Cond, OtherOpT, OtherOpF, "minmaxop", &SI);

373 }

374 }

375

376

377

378

379

380

381 if (TII->getIntrinsicID() == Intrinsic::ldexp) {

382 Value *LdexpVal0 = TII->getArgOperand(0);

383 Value *LdexpExp0 = TII->getArgOperand(1);

384 Value *LdexpVal1 = FII->getArgOperand(0);

385 Value *LdexpExp1 = FII->getArgOperand(1);

391

392 Value *SelectVal = Builder.CreateSelect(Cond, LdexpVal0, LdexpVal1);

393 Value *SelectExp = Builder.CreateSelect(Cond, LdexpExp0, LdexpExp1);

394

396 TII->getType(), Intrinsic::ldexp, {SelectVal, SelectExp});

399 }

400 }

401 }

402

403 auto CreateCmpSel = [&](std::optional P,

404 bool Swapped) -> CmpInst * {

405 if (P)

406 return nullptr;

409 if (!MatchOp)

410 return nullptr;

411 Value *NewSel = Builder.CreateSelect(Cond, OtherOpT, OtherOpF,

412 SI.getName() + ".v", &SI);

413 return new ICmpInst(MatchIsOpZero ? *P

415 MatchOp, NewSel);

416 };

417

418

419

423 if (auto *R =

425 return R;

426 if (auto *R =

429 true))

430 return R;

431 }

432 }

433

434

435

436

437

442 return nullptr;

443

444

446 if (!MatchOp)

447 return nullptr;

448

449

450

451

454 return nullptr;

455

456

457

458

459

460

461

464

465

466 if (BO->getOpcode() == Instruction::SDiv ||

467 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)

469 }

470

471

472 Value *NewSI = Builder.CreateSelect(Cond, OtherOpT, OtherOpF,

473 SI.getName() + ".v", &SI);

474 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;

475 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;

480 return NewBO;

481 }

484 Type *ElementType = TGEP->getSourceElementType();

486 ElementType, Op0, Op1, TGEP->getNoWrapFlags() & FGEP->getNoWrapFlags());

487 }

489 return nullptr;

490}

491

493 if (!C1I.isZero() && !C2I.isZero())

494 return false;

496}

497

498

499

501 Value *FalseVal) {

502

503

508 if (!TVI || !TVI->hasOneUse() || isa(FalseVal))

509 return nullptr;

510

512 unsigned OpToFold = 0;

513 if ((SFO & 1) && FalseVal == TVI->getOperand(0))

514 OpToFold = 1;

515 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))

516 OpToFold = 2;

517

518 if (!OpToFold)

519 return nullptr;

520

523 FMF = SI.getFastMathFlags();

525 TVI->getOpcode(), TVI->getType(), true, FMF.noSignedZeros());

526 Value *OOp = TVI->getOperand(2 - OpToFold);

527

528

529 const APInt *OOpC;

532 (!OOpIsAPInt || isSelect01(C->getUniqueInteger(), *OOpC)))

533 return nullptr;

534

535

536

537

538

539

540

543 return nullptr;

544

545 Value *NewSel = Builder.CreateSelect(SI.getCondition(), Swapped ? C : OOp,

546 Swapped ? OOp : C, "", &SI);

549

550

551

552

553

554

555 NewSelFMF.setNoInfs(TVI->hasNoInfs() ||

558 }

564

567

568

570 }

571 return BO;

572 };

573

574 if (Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal, false))

575 return R;

576

577 if (Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal, true))

578 return R;

579

580 return nullptr;

581}

582

583

584

585

590 const Value *CmpLHS = Cmp->getOperand(0);

591 const Value *CmpRHS = Cmp->getOperand(1);

593

594

595

596

597

598 if (CmpRHS == TVal) {

601 }

602

603

604

606 return nullptr;

607

611 return Builder.CreateBinaryIntrinsic(Intrinsic::smax, TVal, FVal);

612 }

613

617 return Builder.CreateBinaryIntrinsic(Intrinsic::smin, TVal, FVal);

618 }

619

623 return Builder.CreateBinaryIntrinsic(Intrinsic::umax, TVal, FVal);

624 }

625

626

627

633 return Builder.CreateBinaryIntrinsic(Intrinsic::umin, TVal, FVal);

634 }

635

636 return nullptr;

637}

638

639

640

641

642

643

644

645

646

650 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&

653 return nullptr;

654

655

658 return nullptr;

659

660

663

664

665

666

667 if (HasShift &&

671 return nullptr;

672

673 if (!HasShift)

674 X = B;

675

678 return nullptr;

679

680

681

682 Constant *One = ConstantInt::get(SelType, 1);

683 Value *MaskB = HasShift ? Builder.CreateShl(One, Z) : One;

684 Value *FullMask = Builder.CreateOr(Y, MaskB);

685 Value *MaskedX = Builder.CreateAnd(X, FullMask);

686 Value *ICmpNeZero = Builder.CreateIsNotNull(MaskedX);

687 return new ZExtInst(ICmpNeZero, SelType);

688}

689

690

691

692

693

694

701 return nullptr;

702

706 }

707

709 const APInt *C2, *C1;

713 return nullptr;

714

717 return nullptr;

718

720 if (!FI)

721 return nullptr;

722

723 FI->setHasNoSignedWrap(false);

724 FI->setHasNoUnsignedWrap(false);

725 return FVal;

726}

727

728

729

730

731

732

740 return nullptr;

741

750 return nullptr;

751

752

755

760

761 bool IsExact = Ashr->isExact() && cast(TrueVal)->isExact();

762 return Builder.CreateAShr(X, Y, IC->getName(), IsExact);

763 }

764

765 return nullptr;

766}

767

768

769

770

771

772

773

774

775

776

777

778

779

780

781

782

783

784

785

786

787

790 const APInt &AndMask, bool CreateAnd,

792

793 if (!TrueVal->getType()->isIntOrIntVectorTy())

794 return nullptr;

795

796 unsigned C1Log = AndMask.logBase2();

800 bool NeedXor;

802 Y = TrueVal;

804 NeedXor = false;

806 Y = FalseVal;

808 NeedXor = true;

809 } else {

810 return nullptr;

811 }

812

813

814 auto *IdentityC =

816 true);

817 if (IdentityC == nullptr || !IdentityC->isNullValue())

818 return nullptr;

819

820 unsigned C2Log = C2->logBase2();

821

822 bool NeedShift = C1Log != C2Log;

823 bool NeedZExtTrunc = Y->getType()->getScalarSizeInBits() !=

824 V->getType()->getScalarSizeInBits();

825

826

827 if ((NeedShift + NeedXor + NeedZExtTrunc + CreateAnd) >

829 return nullptr;

830

831 if (CreateAnd) {

832

833 V = Builder.CreateAnd(V, ConstantInt::get(V->getType(), AndMask));

834 }

835

836 if (C2Log > C1Log) {

837 V = Builder.CreateZExtOrTrunc(V, Y->getType());

838 V = Builder.CreateShl(V, C2Log - C1Log);

839 } else if (C1Log > C2Log) {

840 V = Builder.CreateLShr(V, C1Log - C2Log);

841 V = Builder.CreateZExtOrTrunc(V, Y->getType());

842 } else

843 V = Builder.CreateZExtOrTrunc(V, Y->getType());

844

845 if (NeedXor)

846 V = Builder.CreateXor(V, *C2);

847

848 auto *Res = Builder.CreateBinOp(BinOp->getOpcode(), Y, V);

850 BO->copyIRFlags(BinOp);

851 return Res;

852}

853

854

855

863 const APInt *NotC, *C;

864

865

869 Constant *OrC = ConstantInt::get(Ty, *C);

870 Value *NewSel = Builder.CreateSelect(Cond, Zero, OrC, "masksel", &Sel);

871 return BinaryOperator::CreateOr(T, NewSel);

872 }

873

874

878 Constant *OrC = ConstantInt::get(Ty, *C);

879 Value *NewSel = Builder.CreateSelect(Cond, OrC, Zero, "masksel", &Sel);

880 return BinaryOperator::CreateOr(F, NewSel);

881 }

882

883 return nullptr;

884}

885

886

887

888

889

890

891

892

893

894

895

896

897

898

901 auto *CondVal = SI.getCondition();

902 auto *TrueVal = SI.getTrueValue();

903 auto *FalseVal = SI.getFalseValue();

906

907

908

909

912 return nullptr;

913

916

917

918

919

920

923 return nullptr;

924

925 bool FreezeY;

932 FreezeY = true;

935 FreezeY = false;

936 } else {

937 return nullptr;

938 }

939

942

943

944

946 return nullptr;

947

949 if (FreezeY) {

953 FalseValI->getOperand(0) == Y

954 ? 0

955 : (FalseValI->getOperand(1) == Y ? 1 : 2),

956 FrY);

957 }

959}

960

961

962

964 const Value *TrueVal,

965 const Value *FalseVal,

970

971

972

976 }

977

979 return nullptr;

980

981

982

985 return Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, A,

986 ConstantInt::get(A->getType(), 1));

987 return nullptr;

988 }

989

991 return nullptr;

992

994

997 }

998

1000 "Unexpected isUnsigned predicate!");

1001

1002

1003

1004

1005

1006 bool IsNegative = false;

1011 IsNegative = true;

1015 return nullptr;

1016

1017

1018

1019 if (IsNegative && !TrueVal->hasOneUse() && !ICI->hasOneUse())

1020 return nullptr;

1021

1022

1023

1024 Value *Result = Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, A, B);

1025 if (IsNegative)

1026 Result = Builder.CreateNeg(Result);

1027 return Result;

1028}

1029

1033

1034

1035 Value *Cmp0 = Cmp->getOperand(0);

1036 Value *Cmp1 = Cmp->getOperand(1);

1040

1041

1042

1043

1047 }

1049 return nullptr;

1050

1051

1052

1056 return Builder.CreateBinaryIntrinsic(

1057 Intrinsic::uadd_sat, Cmp0, ConstantInt::get(Cmp0->getType(), 1));

1058 }

1059 return nullptr;

1060 }

1061

1065

1066

1067 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,

1068 ConstantInt::get(Cmp0->getType(), *C));

1069 }

1070

1071

1072

1076

1077 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,

1078 ConstantInt::get(Cmp0->getType(), *C));

1079 }

1080

1081

1082

1086

1087 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,

1088 ConstantInt::get(Cmp0->getType(), *C));

1089 }

1090

1091

1095 }

1097 return nullptr;

1098

1099

1100

1104

1105

1106 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, X, Y);

1107 }

1108

1109

1110 X = Cmp0;

1111 Y = Cmp1;

1113

1114

1116 return Builder.CreateBinaryIntrinsic(

1118 }

1119

1120

1124

1125

1126 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp1, Y);

1127 }

1128

1129 return nullptr;

1130}

1131

1135

1136 Value *Cmp0 = Cmp->getOperand(0);

1137 Value *Cmp1 = Cmp->getOperand(1);

1141

1142

1146 }

1147

1149 return nullptr;

1150

1151

1152

1153

1156 return Builder.CreateBinaryIntrinsic(

1157 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->getType(), 1));

1158 }

1159 return nullptr;

1160 }

1161

1162

1163

1164

1170

1171

1175 Pred = Flipped->first;

1176 Cmp1 = Flipped->second;

1177 }

1178 }

1179

1180

1184 return Builder.CreateBinaryIntrinsic(

1185 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->getType(), *C));

1186 }

1187

1188

1192 }

1193

1195 return nullptr;

1196

1199

1200

1201 return Builder.CreateBinaryIntrinsic(Intrinsic::sadd_sat, X, Cmp1);

1202 }

1203

1204 return nullptr;

1205}

1206

1209 if (!Cmp->hasOneUse())

1210 return nullptr;

1211

1213 return V;

1214

1216 return V;

1217

1218 return nullptr;

1219}

1220

1221

1226 if (!TI || !FI)

1227 return nullptr;

1228

1229

1231 Value *A = Cmp->getOperand(0);

1232 Value *B = Cmp->getOperand(1);

1233

1234

1238 }

1239

1240

1241

1245 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&

1246 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {

1247

1248

1249

1250

1251

1252

1253 TI->setHasNoUnsignedWrap(false);

1254 if (!TI->hasNoSignedWrap())

1255 TI->setHasNoSignedWrap(TI->hasOneUse());

1256 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI, Builder.getTrue());

1257 }

1258

1259

1263 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,

1264 Builder.getFalse());

1265 }

1266

1267

1271 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,

1272 Builder.getFalse());

1273 }

1274

1275

1279 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,

1280 Builder.getFalse());

1281 }

1282

1283

1287 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,

1288 Builder.getFalse());

1289 }

1290

1291 return nullptr;

1292}

1293

1294

1295

1296

1297

1298

1299

1300

1301

1302

1303

1305 Value *FalseVal,

1307 unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits();

1309 return nullptr;

1310

1313

1315 if (match(FalseVal,

1317 return nullptr;

1318

1320 return nullptr;

1321

1323 return nullptr;

1324

1328 return nullptr;

1329

1331 II->getModule(), Intrinsic::cttz, II->getType());

1333}

1334

1335

1336

1337

1338

1339

1340

1341

1342

1343

1344

1345

1346

1352

1353

1355 return nullptr;

1356

1360 std::swap(SelectArg, ValueOnZero);

1361

1362

1366 Count = SelectArg;

1367

1368

1369

1373 return nullptr;

1374

1375

1376

1377

1378 if ((X != CmpLHS || match(CmpRHS, m_Zero())) &&

1381 return nullptr;

1382

1384

1385

1386

1387 unsigned SizeOfInBits = Count->getType()->getScalarSizeInBits();

1389

1390

1392

1393 II->dropPoisonGeneratingAnnotations();

1395 return SelectArg;

1396 }

1397

1398

1399

1400

1401 if (II->hasOneUse() && SelectArg->hasOneUse() &&

1404

1405 II->dropUBImplyingAttrsAndMetadata();

1407 }

1408

1409 return nullptr;

1410}

1411

1415

1416 if (TrueVal->getType()->isIntOrIntVectorTy())

1417 return nullptr;

1418

1424 return nullptr;

1425

1426

1430 ConstantInt::get(Type::getInt1Ty(Cmp.getContext()), IntMinIsPoison);

1433

1435 return IC.Builder.CreateNeg(Abs);

1436 return Abs;

1437 }

1438

1442 }

1443

1444 return nullptr;

1445}

1446

1448 unsigned Depth) {

1449

1451 return false;

1452

1454

1456 if (I || I->hasOneUse() ||

1458 return false;

1459

1460

1462 return false;

1463

1465 for (Use &U : I->operands()) {

1466 if (U == Old) {

1470 } else {

1472 }

1473 }

1475}

1476

1477

1478

1479

1480

1481

1482

1483

1484

1485

1486

1487

1488

1489

1490

1491

1492

1495

1496

1498 bool Swapped = false;

1499 if (Cmp.isEquivalence(true)) {

1501 Swapped = true;

1502 } else if (Cmp.isEquivalence()) {

1503 return nullptr;

1504 }

1505

1506 Value *CmpLHS = Cmp.getOperand(0), *CmpRHS = Cmp.getOperand(1);

1507 auto ReplaceOldOpWithNewOp = [&](Value *OldOp,

1508 Value *NewOp) -> Instruction * {

1509

1510

1511

1512

1513

1514

1516 return nullptr;

1517

1519 true)) {

1520

1521

1522

1526

1527

1528

1529

1530

1536 return nullptr;

1537 }

1538 }

1539

1540

1541

1542

1543

1544

1545

1550 return &Sel;

1551 return nullptr;

1552 };

1553

1555 if (CanReplaceCmpLHSWithRHS) {

1556 if (Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))

1557 return R;

1558 }

1560 if (CanReplaceCmpRHSWithLHS) {

1561 if (Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))

1562 return R;

1563 }

1564

1566 if (!FalseInst)

1567 return nullptr;

1568

1569

1570

1571

1572

1573

1574

1575

1576

1578 if ((CanReplaceCmpLHSWithRHS &&

1580 false,

1581 &DropFlags) == TrueVal) ||

1582 (CanReplaceCmpRHSWithLHS &&

1584 false,

1585 &DropFlags) == TrueVal)) {

1586 for (Instruction *I : DropFlags) {

1587 I->dropPoisonGeneratingAnnotations();

1589 }

1590

1592 }

1593

1594 return nullptr;

1595}

1596

1597

1598

1599

1600

1601

1602

1603

1604

1605

1606

1607

1608

1612

1614 return nullptr;

1615

1616 if (match(YeqZ,

1619

1620 if (match(YeqZ,

1622 return nullptr;

1623

1626 return nullptr;

1627

1628 if (match(XeqY,

1630 return nullptr;

1631

1634}

1635

1636

1637

1638

1639

1640

1641

1642

1643

1644

1645

1646

1647

1648

1649

1655

1656

1657

1659 return nullptr;

1665 return nullptr;

1666

1670 }

1671

1672

1673

1674 switch (Pred0) {

1677

1678

1679

1683 return nullptr;

1684 break;

1687

1688

1693 return nullptr;

1696 break;

1697 default:

1698 return nullptr;

1699 }

1700

1701

1702

1704 return nullptr;

1705

1706

1707

1708 if (Cmp00->getType() != X->getType() && X->hasOneUse())

1710

1711

1712

1714 if (Cmp00 == X)

1716 else if (match(Cmp00,

1719 return nullptr;

1720

1724 Value *ReplacementLow, *ReplacementHigh;

1726 m_Value(ReplacementHigh))) ||

1730 return nullptr;

1731

1733 return nullptr;

1734

1735

1736

1737

1738

1739 switch (Pred1) {

1741 break;

1743

1744

1745

1746 return nullptr;

1748

1749

1754 return nullptr;

1756 [[fallthrough]];

1758

1759

1761 std::swap(ReplacementLow, ReplacementHigh);

1762 break;

1763 default:

1764 return nullptr;

1765 }

1767 "Unexpected predicate type.");

1768

1769

1772

1775 "Unexpected predicate type.");

1777 std::swap(ThresholdLowIncl, ThresholdHighExcl);

1778

1779

1782 if (!Precond1 || match(Precond1, m_One()))

1783 return nullptr;

1784

1787 if (!Precond2 || match(Precond2, m_One()))

1788 return nullptr;

1789

1790

1791

1792

1793 if (X->getType() != Sel0.getType()) {

1797 return nullptr;

1799 ReplacementLow =

1801 ReplacementHigh =

1803 assert(ReplacementLow && ReplacementHigh &&

1804 "Constant folding of ImmConstant cannot fail");

1805 }

1806

1807

1810 Value *MaybeReplacedLow =

1811 Builder.CreateSelect(ShouldReplaceLow, ReplacementLow, X);

1812

1813

1814

1816 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);

1818}

1819

1820

1821

1822

1823

1824

1825

1826

1827

1829tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,

1837 return nullptr;

1838

1839

1841 return nullptr;

1842

1843

1844

1846 return nullptr;

1847

1848

1849

1851 return nullptr;

1852

1853

1854

1855

1857 return nullptr;

1858

1859

1860 Value *SelVal0, *SelVal1;

1862

1863

1866 return nullptr;

1867

1868

1869 auto MatchesSelectValue = [SelVal0, SelVal1](Constant *C) {

1870 return C->isElementWiseEqual(SelVal0) || C->isElementWiseEqual(SelVal1);

1871 };

1872

1873

1874 if (MatchesSelectValue(C0))

1875 return nullptr;

1876

1877

1879 if (!FlippedStrictness)

1880 return nullptr;

1881

1882

1883 if (!MatchesSelectValue(FlippedStrictness->second))

1884 return nullptr;

1885

1886

1889

1892 Cmp.getName() + ".inv");

1896

1897 return &Sel;

1898}

1899

1903 if (Cmp->hasOneUse())

1904 return nullptr;

1905

1906 const APInt *CmpC;

1908 return nullptr;

1909

1910

1915

1916

1920

1921 return nullptr;

1922}

1923

1926 const APInt *CmpC;

1930 return nullptr;

1931

1932

1933 Value *TVal = SI.getTrueValue();

1934 Value *FVal = SI.getFalseValue();

1936

1939

1942

1945

1948 }

1949

1950

1951

1959 else

1960 return nullptr;

1961

1963 const APInt *OpC;

1967 if (R == *C) {

1968 Op->dropPoisonGeneratingFlags();

1969 return Op;

1970 }

1971 }

1973 MMI && MMI->getLHS() == V && match(MMI->getRHS(), m_APInt(OpC))) {

1975 {InvDomCR, ConstantRange(*OpC)});

1976 if (R == *C) {

1977 MMI->dropPoisonGeneratingAnnotations();

1978 return MMI;

1979 }

1980 }

1981

1982 return nullptr;

1983}

1984

1985

1986

1989 Value *FalseVal) {

1991

1993 return nullptr;

1994

1997

1999 return nullptr;

2000

2004 return nullptr;

2005

2008

2015 } else {

2016 return nullptr;

2017 }

2018

2020 return nullptr;

2021

2022 return new ICmpInst(Pred, CmpLHS, B);

2023}

2024

2029 return nullptr;

2030

2035

2038

2040 foldSelectWithExtremeEqCond(CmpLHS, CmpRHS, TrueVal, FalseVal))

2041 return Res;

2042

2043 return nullptr;

2044}

2045

2046

2047

2050 Value *FalseVal) {

2054

2056 return nullptr;

2057

2059 return nullptr;

2060

2064 }

2065

2067 return nullptr;

2068

2069 bool IsIntrinsic;

2070 unsigned Opcode;

2072 Opcode = BOp->getOpcode();

2073 IsIntrinsic = false;

2074

2075

2076

2077

2079 return nullptr;

2080

2082 return nullptr;

2083

2086 return nullptr;

2087 Opcode = II->getIntrinsicID();

2088 IsIntrinsic = true;

2089 } else {

2090 return nullptr;

2091 }

2092

2095 const DataLayout &DL = Cmp->getDataLayout();

2097

2102 };

2103

2104 if (C3 == FoldBinaryOpOrIntrinsic(C1, C2)) {

2106 RHS = C1;

2107 } else if (Flipped && C3 == FoldBinaryOpOrIntrinsic(Flipped->second, C2)) {

2109 RHS = Flipped->second;

2110 } else {

2111 return nullptr;

2112 }

2113

2115 Value *MinMax = Builder.CreateBinaryIntrinsic(MinMaxID, X, RHS);

2116 if (IsIntrinsic)

2117 return Builder.CreateBinaryIntrinsic(Opcode, MinMax, C2);

2118

2120 Value *BinOp = Builder.CreateBinOp(BinOpc, MinMax, C2);

2121

2122

2123

2125 if (BinOpc == Instruction::Add || BinOpc == Instruction::Sub ||

2126 BinOpc == Instruction::Mul) {

2129 willNotOverflow(BinOpc, RHS, C2, *BinOpInst, true))

2130 BinOpInst->setHasNoSignedWrap();

2132 willNotOverflow(BinOpc, RHS, C2, *BinOpInst, false))

2133 BinOpInst->setHasNoUnsignedWrap();

2134 }

2135 }

2136 return BinOp;

2137}

2138

2139

2140

2141

2142

2143

2144

2145

2146

2147

2148

2149

2150

2151static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(

2153 if (SI.hasOneUse() || !ICI->hasOneUse())

2154 return nullptr;

2157 const APInt *Constant1, *Constant2;

2158 if (match(SI.getCondition(),

2165 return nullptr;

2166

2173 return nullptr;

2174

2175 auto *Ty = A->getType();

2178

2179

2181 return nullptr;

2182

2183 APInt AdjAP1 = *Constant1 - MostSignificantBit + 1;

2184 APInt AdjAP2 = *Constant2 - MostSignificantBit + 1;

2185

2186 auto *Adj1 = ConstantInt::get(Ty, AdjAP1);

2187 auto *Adj2 = ConstantInt::get(Ty, AdjAP2);

2188

2192 Constant *MSBConst = ConstantInt::get(Ty, MostSignificantBit);

2193 return BinaryOperator::CreateAnd(Or, MSBConst);

2194}

2195

2196

2200 canonicalizeSPF(*ICI, SI.getTrueValue(), SI.getFalseValue(), *this))

2202

2203 if (Value *V = foldSelectInstWithICmpConst(SI, ICI, Builder))

2205

2206 if (Value *V = canonicalizeClampLike(SI, *ICI, Builder, *this))

2208

2209 if (Instruction *NewSel =

2210 tryToReuseConstantFromSelectInComparison(SI, *ICI, *this))

2211 return NewSel;

2212 if (Instruction *Folded =

2213 foldICmpUSubSatWithAndForMostSignificantBitCmp(SI, ICI, Builder))

2214 return Folded;

2215

2216

2223

2224 if (Instruction *NewSel = foldSelectICmpEq(SI, ICI, *this))

2225 return NewSel;

2226

2227

2228

2229

2230

2234 InstCombiner::BuilderTy::InsertPointGuard Guard(Builder);

2235 Builder.SetInsertPoint(&SI);

2238 SI.swapValues();

2239 SI.swapProfMetadata();

2240 return &SI;

2241 }

2242

2245

2246 if (Instruction *V =

2248 return V;

2249

2252

2253 if (Instruction *V = foldSelectCtlzToCttz(ICI, TrueVal, FalseVal, Builder))

2254 return V;

2255

2256 if (Instruction *V = foldSelectZeroOrOnes(ICI, TrueVal, FalseVal, Builder))

2257 return V;

2258

2261

2262 if (Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *this))

2264

2267

2270

2273

2276

2278}

2279

2280

2281

2288 return nullptr;

2289

2290 if (C == A || C == B) {

2291

2292

2293

2296 }

2297

2298 return nullptr;

2299}

2300

2301

2302

2305 Value *CondVal = SI.getCondition();

2310 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())

2311 return nullptr;

2312

2313 Instruction *AddOp = nullptr, *SubOp = nullptr;

2314 if ((TI->getOpcode() == Instruction::Sub &&

2315 FI->getOpcode() == Instruction::Add) ||

2316 (TI->getOpcode() == Instruction::FSub &&

2317 FI->getOpcode() == Instruction::FAdd)) {

2318 AddOp = FI;

2319 SubOp = TI;

2320 } else if ((FI->getOpcode() == Instruction::Sub &&

2321 TI->getOpcode() == Instruction::Add) ||

2322 (FI->getOpcode() == Instruction::FSub &&

2323 TI->getOpcode() == Instruction::FAdd)) {

2324 AddOp = TI;

2325 SubOp = FI;

2326 }

2327

2328 if (AddOp) {

2329 Value *OtherAddOp = nullptr;

2330 if (SubOp->getOperand(0) == AddOp->getOperand(0)) {

2332 } else if (SubOp->getOperand(0) == AddOp->getOperand(1)) {

2334 }

2335

2336 if (OtherAddOp) {

2337

2338

2339 Value *NegVal;

2340 if (SI.getType()->isFPOrFPVectorTy()) {

2341 NegVal = Builder.CreateFNeg(SubOp->getOperand(1));

2344 Flags &= SubOp->getFastMathFlags();

2345 NegInst->setFastMathFlags(Flags);

2346 }

2347 } else {

2348 NegVal = Builder.CreateNeg(SubOp->getOperand(1));

2349 }

2350

2351 Value *NewTrueOp = OtherAddOp;

2352 Value *NewFalseOp = NegVal;

2353 if (AddOp != TI)

2354 std::swap(NewTrueOp, NewFalseOp);

2355 Value *NewSel = Builder.CreateSelect(CondVal, NewTrueOp, NewFalseOp,

2356 SI.getName() + ".p", &SI);

2357

2358 if (SI.getType()->isFPOrFPVectorTy()) {

2360 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);

2361

2363 Flags &= SubOp->getFastMathFlags();

2365 return RI;

2366 } else

2367 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);

2368 }

2369 }

2370 return nullptr;

2371}

2372

2373

2374

2375

2376

2377

2380 Value *CondVal = SI.getCondition();

2383

2387 return nullptr;

2388

2391

2392 auto IsSignedSaturateLimit = [&](Value *Limit, bool IsAdd) {

2394

2400 return false;

2401

2402 auto IsZeroOrOne = [](const APInt &C) { return C.isZero() || C.isOne(); };

2408 };

2409

2410 if (Op != X && Op != Y)

2411 return false;

2412

2413 if (IsAdd) {

2414

2415

2416

2417

2419 IsMinMax(TrueVal, FalseVal))

2420 return true;

2421

2422

2423

2424

2426 IsMinMax(FalseVal, TrueVal))

2427 return true;

2428 } else {

2429

2430

2432 IsMinMax(TrueVal, FalseVal))

2433 return true;

2434

2435

2437 IsMinMax(FalseVal, TrueVal))

2438 return true;

2439

2440

2442 IsMinMax(FalseVal, TrueVal))

2443 return true;

2444

2445

2447 IsMinMax(TrueVal, FalseVal))

2448 return true;

2449 }

2450

2451 return false;

2452 };

2453

2455 if (II->getIntrinsicID() == Intrinsic::uadd_with_overflow &&

2457

2458 NewIntrinsicID = Intrinsic::uadd_sat;

2459 else if (II->getIntrinsicID() == Intrinsic::usub_with_overflow &&

2461

2462 NewIntrinsicID = Intrinsic::usub_sat;

2463 else if (II->getIntrinsicID() == Intrinsic::sadd_with_overflow &&

2464 IsSignedSaturateLimit(TrueVal, true))

2465

2466

2467

2468

2469

2470

2471

2472

2473 NewIntrinsicID = Intrinsic::sadd_sat;

2474 else if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow &&

2475 IsSignedSaturateLimit(TrueVal, false))

2476

2477

2478

2479

2480

2481

2482

2483

2484 NewIntrinsicID = Intrinsic::ssub_sat;

2485 else

2486 return nullptr;

2487

2489 NewIntrinsicID, SI.getType());

2491}

2492

2497 return nullptr;

2498

2502 return nullptr;

2503

2504 auto ExtOpcode = ExtInst->getOpcode();

2505 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)

2506 return nullptr;

2507

2508

2509

2515 (!Cmp || Cmp->getOperand(0)->getType() != SmallType))

2516 return nullptr;

2517

2518

2519

2522 if (TruncC && ExtInst->hasOneUse()) {

2526

2527

2528

2529 Value *NewSel = Builder.CreateSelect(Cond, X, TruncCVal, "narrow", &Sel);

2531 }

2532

2533 return nullptr;

2534}

2535

2536

2537

2539 Value *CondVal = SI.getCondition();

2543 return nullptr;

2544

2545 unsigned NumElts = CondValTy->getNumElements();

2547 Mask.reserve(NumElts);

2548 for (unsigned i = 0; i != NumElts; ++i) {

2550 if (!Elt)

2551 return nullptr;

2552

2554

2555 Mask.push_back(i);

2557

2558 Mask.push_back(i + NumElts);

2560

2561

2562

2563 return nullptr;

2564 } else {

2565

2566 return nullptr;

2567 }

2568 }

2569

2571}

2572

2573

2574

2575

2576

2580 if (!Ty)

2581 return nullptr;

2582

2583

2586 return nullptr;

2587

2588

2589

2590

2593}

2594

2595

2596

2597

2603

2607 return nullptr;

2608

2609

2610

2611 if (TVal == A || TVal == B || FVal == A || FVal == B)

2612 return nullptr;

2613

2616 return nullptr;

2617

2618

2619 Value *TSrc, *FSrc;

2622 return nullptr;

2623

2624

2625

2626

2628 if (TSrc == C && FSrc == D) {

2629

2630

2632 } else if (TSrc == D && FSrc == C) {

2633

2634

2636 } else {

2637 return nullptr;

2638 }

2640}

2641

2642

2643

2644

2645

2646

2647

2648

2649

2650

2651

2652

2653

2654

2655

2656

2657

2658

2659

2660

2661

2662

2663

2664

2666

2667

2668

2669

2672 if (!Extract)

2673 return nullptr;

2674 if (Extract->getIndices()[0] != I)

2675 return nullptr;

2677 };

2678

2679

2680

2681 if (SI.hasOneUse())

2683 if (Select->getCondition() == SI.getCondition())

2684 if (Select->getFalseValue() == SI.getTrueValue() ||

2685 Select->getTrueValue() == SI.getFalseValue())

2686 return nullptr;

2687

2688

2689 auto *CmpXchg = isExtractFromCmpXchg(SI.getCondition(), 1);

2690 if (!CmpXchg)

2691 return nullptr;

2692

2693

2694

2695

2696 if (auto *X = isExtractFromCmpXchg(SI.getTrueValue(), 0))

2697 if (X == CmpXchg && X->getCompareOperand() == SI.getFalseValue())

2698 return SI.getFalseValue();

2699

2700

2701

2702

2703 if (auto *X = isExtractFromCmpXchg(SI.getFalseValue(), 0))

2704 if (X == CmpXchg && X->getCompareOperand() == SI.getTrueValue())

2705 return SI.getFalseValue();

2706

2707 return nullptr;

2708}

2709

2710

2711

2712

2713

2714

2715

2716

2717

2720

2723 return nullptr;

2724

2727 return nullptr;

2728

2729 Value *SV0, *SV1, *SA0, *SA1;

2735 return nullptr;

2736

2737

2738 if (Or0->getOpcode() == BinaryOperator::LShr) {

2742 }

2744 Or1->getOpcode() == BinaryOperator::LShr &&

2745 "Illegal or(shift,shift) pair");

2746

2747

2750 ShAmt = SA0;

2752 ShAmt = SA1;

2753 else

2754 return nullptr;

2755

2756

2757

2758

2759

2760 bool IsFshl = (ShAmt == SA0);

2762 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))

2763 return nullptr;

2764

2765

2769 return nullptr;

2770

2771

2772

2773 if (SV0 != SV1) {

2778 }

2779

2780

2781

2782 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;

2787}

2788

2795

2796

2797

2802 return nullptr;

2803

2804 assert(TC != FC && "Expected equal select arms to simplify");

2805

2808 bool IsTrueIfSignSet;

2812 isSignBitCheck(Pred, *C, IsTrueIfSignSet) || X->getType() != SelType)

2813 return nullptr;

2814

2815

2816

2817

2818

2819

2820

2821 if (IsTrueIfSignSet ^ TC->isNegative())

2823

2824

2825

2826 Value *MagArg = ConstantFP::get(SelType, abs(*TC));

2830}

2831

2834 return nullptr;

2835

2840

2845 I->copyIRFlags(&Sel);

2848 M, Intrinsic::vector_reverse, V->getType());

2850 };

2851

2853

2856 return createSelReverse(C, X, Y);

2857

2858

2860 return createSelReverse(C, X, FVal);

2861 }

2862

2865 return createSelReverse(C, TVal, Y);

2866 }

2867

2869 if (!VecTy)

2870 return nullptr;

2871

2872 unsigned NumElts = VecTy->getNumElements();

2873 APInt PoisonElts(NumElts, 0);

2876 if (V != &Sel)

2878 return &Sel;

2879 }

2880

2881

2882

2883

2884 ArrayRef Mask;

2888 if (X == FVal) {

2889

2891 return new ShuffleVectorInst(X, NewSel, Mask);

2892 }

2893 if (Y == FVal) {

2894

2896 return new ShuffleVectorInst(NewSel, Y, Mask);

2897 }

2898 }

2902 if (X == TVal) {

2903

2905 return new ShuffleVectorInst(X, NewSel, Mask);

2906 }

2907 if (Y == TVal) {

2908

2910 return new ShuffleVectorInst(NewSel, Y, Mask);

2911 }

2912 }

2913

2914 return nullptr;

2915}

2916

2920

2921

2922 auto *IDomNode = DT[BB]->getIDom();

2923 if (!IDomNode)

2924 return nullptr;

2925 BasicBlock *IDom = IDomNode->getBlock();

2926

2928 Value *IfTrue, *IfFalse;

2940 } else

2941 return nullptr;

2942

2943

2944 if (TrueSucc == FalseSucc)

2945 return nullptr;

2946

2947

2948

2949

2950

2951

2956

2962 else

2963 return nullptr;

2964

2966 if (!DT.dominates(Insn, Pred->getTerminator()))

2967 return nullptr;

2968 }

2969

2974 PN->takeName(&Sel);

2975 return PN;

2976}

2977

2980

2985 CandidateBlocks.insert(I->getParent());

2986

2987 for (BasicBlock *BB : CandidateBlocks)

2988 if (auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))

2989 return PN;

2990 return nullptr;

2991}

2992

2993

2994

2995

2996

2997

2998

3001 Value *CondVal = SI.getCondition();

3004

3006 Value *Op, *RemRes, *Remainder;

3008 bool TrueIfSigned = false;

3009

3012 return nullptr;

3013

3014

3015

3016 if (!TrueIfSigned)

3018

3019 auto FoldToBitwiseAnd = [&](Value *Remainder) -> Instruction * {

3022 return BinaryOperator::CreateAnd(Op, Add);

3023 };

3024

3025

3026

3027

3028

3029

3033 FalseVal == RemRes)

3034 return FoldToBitwiseAnd(Remainder);

3035

3036

3037

3038

3039

3042 FalseVal == RemRes)

3043 return FoldToBitwiseAnd(ConstantInt::get(RemRes->getType(), 2));

3044

3045 return nullptr;

3046}

3047

3048

3049static Value *simplifyNestedSelectsUsingImpliedCond(SelectInst &SI,

3051 bool CondIsTrue,

3053 Value *InnerCondVal = SI.getCondition();

3054 Value *InnerTrueVal = SI.getTrueValue();

3055 Value *InnerFalseVal = SI.getFalseValue();

3057 "The type of inner condition must match with the outer.");

3058 if (auto Implied = isImpliedCondition(CondVal, InnerCondVal, DL, CondIsTrue))

3059 return *Implied ? InnerTrueVal : InnerFalseVal;

3060 return nullptr;

3061}

3062

3063Instruction *InstCombinerImpl::foldAndOrOfSelectUsingImpliedCond(Value *Op,

3065 bool IsAnd) {

3066 assert(Op->getType()->isIntOrIntVectorTy(1) &&

3067 "Op must be either i1 or vector of i1.");

3068 if (SI.getCondition()->getType() != Op->getType())

3069 return nullptr;

3070 if (Value *V = simplifyNestedSelectsUsingImpliedCond(SI, Op, IsAnd, DL))

3071 return createSelectInstWithUnknownProfile(

3074 return nullptr;

3075}

3076

3077

3078

3081 Value *CondVal = SI.getCondition();

3082

3083 bool ChangedFMF = false;

3084 for (bool Swap : {false, true}) {

3086 Value *X = SI.getFalseValue();

3088

3089 if (Swap)

3091

3093 continue;

3094

3095

3096

3097

3098

3099

3108 }

3112 }

3113 }

3114

3116 return nullptr;

3117

3118

3119

3120

3122 if (FMF.noNaNs() && SI.hasNoNaNs()) {

3123 SI.setHasNoNaNs(true);

3124 ChangedFMF = true;

3125 }

3126 if (FMF.noInfs() && SI.hasNoInfs()) {

3127 SI.setHasNoInfs(true);

3128 ChangedFMF = true;

3129 }

3130

3131

3134 SI.setHasNoNaNs(true);

3135 ChangedFMF = true;

3136 }

3137

3138

3139

3140

3141

3142

3143

3144

3145

3146

3147

3148 if (SI.hasNoSignedZeros() &&

3150 return nullptr;

3151 if (SI.hasNoNaNs() &&

3153 return nullptr;

3154

3155 if (Swap)

3157

3162

3163 if (IsLTOrLE) {

3166 }

3167 if (IsGTOrGE) {

3169 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);

3171 return NewFNeg;

3172 }

3173 }

3174

3175

3176

3177

3178 for (bool Swap : {false, true}) {

3180 Value *X = SI.getFalseValue();

3181

3182 if (Swap)

3184

3187 bool TrueIfSigned;

3188 if (match(CondVal,

3191 continue;

3193 return nullptr;

3194 if (Swap == TrueIfSigned && !CondVal->hasOneUse() && TrueVal->hasOneUse())

3195 return nullptr;

3196

3197

3198

3200 if (Swap != TrueIfSigned)

3203 }

3204

3205 return ChangedFMF ? &SI : nullptr;

3206}

3207

3208

3209

3210

3211

3212

3213

3214

3215

3216

3217

3218

3219

3220

3221

3223foldRoundUpIntegerWithPow2Alignment(SelectInst &SI,

3226 Value *X = SI.getTrueValue();

3227 Value *XBiasedHighBits = SI.getFalseValue();

3228

3230 Value *XLowBits;

3233 return nullptr;

3234

3237

3238

3239

3240 const APInt *LowBitMaskCst;

3242 return nullptr;

3243

3244

3245 const APInt *BiasCst, *HighBitMaskCst;

3246 if (match(XBiasedHighBits,

3249 match(XBiasedHighBits,

3252 return nullptr;

3253

3254 if (!LowBitMaskCst->isMask())

3255 return nullptr;

3256

3257 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;

3258 if (InvertedLowBitMaskCst != *HighBitMaskCst)

3259 return nullptr;

3260

3261 APInt AlignmentCst = *LowBitMaskCst + 1;

3262

3263 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)

3264 return nullptr;

3265

3266 if (!XBiasedHighBits->hasOneUse()) {

3267

3268 if (*BiasCst == *LowBitMaskCst && impliesPoison(XBiasedHighBits, X))

3269 return XBiasedHighBits;

3270 return nullptr;

3271 }

3272

3273

3274 Type *Ty = X->getType();

3275 Value *XOffset = Builder.CreateAdd(X, ConstantInt::get(Ty, *LowBitMaskCst),

3276 X->getName() + ".biased");

3277 Value *R = Builder.CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));

3278 R->takeName(&SI);

3279 return R;

3280}

3281

3282namespace {

3283struct DecomposedSelect {

3287};

3288}

3289

3290

3291

3292

3293

3295foldSelectOfSymmetricSelect(SelectInst &OuterSelVal,

3297

3298 Value *OuterCond, *InnerCond, *InnerTrueVal, *InnerFalseVal;

3300 &OuterSelVal,

3303 m_Value(InnerFalseVal))),

3307 return nullptr;

3308

3310 return nullptr;

3311

3314}

3315

3316

3317

3318

3319

3320

3321

3322

3325

3326 DecomposedSelect OuterSel;

3327 match(&OuterSelVal,

3329 m_Value(OuterSel.FalseVal)));

3330

3331

3333 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);

3334

3335

3337 return nullptr;

3338

3339

3341 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;

3342

3343

3346 return nullptr;

3347

3348

3349 DecomposedSelect InnerSel;

3350 if (match(InnerSelVal,

3352 m_Value(InnerSel.FalseVal))))

3353 return nullptr;

3354

3355

3357 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);

3358

3359 Value *AltCond = nullptr;

3360 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](auto m_InnerCond) {

3361

3362

3363

3364

3365 return IsAndVariant ? match(OuterSel.Cond,

3369 };

3370

3371

3372

3373

3374

3375 if (matchOuterCond(m_Specific(InnerSel.Cond))) {

3376

3379

3380 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);

3381 InnerSel.Cond = NotInnerCond;

3382 } else

3383 return nullptr;

3384

3386 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,

3387 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);

3388 SelInner->takeName(InnerSelVal);

3390 IsAndVariant ? SelInner : InnerSel.TrueVal,

3391 !IsAndVariant ? SelInner : InnerSel.FalseVal);

3392}

3393

3394

3395

3396

3397static bool impliesPoisonOrCond(const Value *ValAssumedPoison, const Value *V,

3400 return true;

3401

3402

3403

3405 Value *LHS = ICmp->getOperand(0);

3406 const APInt *RHSC1;

3407 const APInt *RHSC2;

3409 if (ICmp->hasSameSign() &&

3420 *RHSC2);

3421 }

3422 }

3423

3424 return false;

3425}

3426

3428 Value *CondVal = SI.getCondition();

3431 Type *SelType = SI.getType();

3432

3433

3434

3435

3438 return nullptr;

3439

3443

3444

3445

3446

3448 if (impliesPoisonOrCond(FalseVal, CondVal, false)) {

3449

3450 return BinaryOperator::CreateOr(CondVal, FalseVal);

3451 }

3452

3454 impliesPoisonOrCond(FalseVal, B, false)) {

3455

3457 SI, Builder.CreateLogicalOr(A, Builder.CreateOr(B, FalseVal), "",

3459 ? nullptr

3461 }

3462

3463

3469 auto AndFactorization = [&](Value *Common, Value *InnerCond,

3470 Value *InnerVal,

3471 bool SelFirst = false) -> Instruction * {

3472 Value *InnerSel = Builder.CreateSelect(InnerCond, One, InnerVal);

3473 if (SelFirst)

3475 if (FalseLogicAnd || (CondLogicAnd && Common == A))

3477 else

3478 return BinaryOperator::CreateAnd(Common, InnerSel);

3479 };

3480

3481 if (A == C)

3482 return AndFactorization(A, B, D);

3483 if (A == D)

3484 return AndFactorization(A, B, C);

3485 if (B == C)

3486 return AndFactorization(B, A, D);

3487 if (B == D)

3488 return AndFactorization(B, A, C, CondLogicAnd && FalseLogicAnd);

3489 }

3490 }

3491

3493 if (impliesPoisonOrCond(TrueVal, CondVal, true)) {

3494

3495 return BinaryOperator::CreateAnd(CondVal, TrueVal);

3496 }

3497

3499 impliesPoisonOrCond(TrueVal, B, true)) {

3500

3502 SI, Builder.CreateLogicalAnd(A, Builder.CreateAnd(B, TrueVal), "",

3504 ? nullptr

3506 }

3507

3508

3514 auto OrFactorization = [&](Value *Common, Value *InnerCond,

3515 Value *InnerVal,

3516 bool SelFirst = false) -> Instruction * {

3517 Value *InnerSel = Builder.CreateSelect(InnerCond, InnerVal, Zero);

3518 if (SelFirst)

3520 if (TrueLogicOr || (CondLogicOr && Common == A))

3522 else

3523 return BinaryOperator::CreateOr(Common, InnerSel);

3524 };

3525

3526 if (A == C)

3527 return OrFactorization(A, B, D);

3528 if (A == D)

3529 return OrFactorization(A, B, C);

3530 if (B == C)

3531 return OrFactorization(B, A, D);

3532 if (B == D)

3533 return OrFactorization(B, A, C, CondLogicOr && TrueLogicOr);

3534 }

3535 }

3536

3537

3538

3539

3541 Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());

3543 SelectInst *NewSI =

3546 return NewSI;

3547 }

3548

3550 Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());

3552 SelectInst *NewSI =

3555 return NewSI;

3556 }

3557

3558

3559

3564 SelectInst *NewSI =

3568 }

3569

3570

3571

3576 SelectInst *NewSI =

3580 }

3581

3582

3586

3590

3591

3594 return BinaryOperator::CreateXor(A, B);

3595

3596

3597 if (match(CondVal,

3599 Value *OrV = Builder.CreateSelect(C, One, FalseVal);

3601 }

3602

3605 Value *OrV = Builder.CreateSelect(NotC, One, TrueVal);

3607 }

3608 }

3609

3612 Value *AndV = Builder.CreateSelect(NotC, FalseVal, Zero);

3614 }

3615 }

3616

3617 if (match(CondVal,

3619 Value *AndV = Builder.CreateSelect(C, TrueVal, Zero);

3621 }

3622

3624 Use *Y = nullptr;

3628 auto *FI = new FreezeInst(*Y, (*Y)->getName() + ".fr");

3632 }

3633

3634 if (auto *V = foldBooleanAndOr(CondVal, Op1, SI, IsAnd,

3635 true))

3637 }

3638

3639

3640

3641

3645 if (Res && *Res == false)

3647 }

3651 if (Res && *Res == false)

3653 }

3654

3655

3656

3660 if (Res && *Res == true)

3662 }

3666 if (Res && *Res == true)

3668 }

3669

3672

3673

3674

3675

3676

3681 bool MayNeedFreeze = SelCond && SelFVal &&

3682 match(SelFVal->getTrueValue(),

3684 if (MayNeedFreeze)

3687 Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;

3689 SelCond) {

3691 } else if (match(FalseVal,

3693 SelFVal) {

3696 return NewSI;

3697 } else {

3698 return createSelectInstWithUnknownProfile(C, A, B);

3699 }

3700 }

3702 }

3703

3704

3705

3706

3707

3712 bool MayNeedFreeze = SelCond && SelFVal &&

3713 match(SelCond->getTrueValue(),

3715 if (MayNeedFreeze)

3718 Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;

3720 SelCond) {

3723 return NewSI;

3725 SelFVal) {

3727 } else {

3728 return createSelectInstWithUnknownProfile(C, B, A);

3729 }

3730 }

3732 }

3733 }

3734

3735 return nullptr;

3736}

3737

3738

3739

3743 bool &ShouldDropNoWrap) {

3744

3745

3746

3747

3748

3749

3750

3751

3752

3753

3754

3755

3756

3757

3758

3759

3760

3761

3762

3765

3766 ShouldDropNoWrap = false;

3767

3768

3769

3770

3771

3772 auto MatchForward = [&](Value *CommonAncestor) {

3773 const APInt *C = nullptr;

3774 if (CtlzOp == CommonAncestor)

3775 return true;

3777 ShouldDropNoWrap = true;

3778 CR = CR.add(*C);

3779 return true;

3780 }

3782 ShouldDropNoWrap = true;

3784 return true;

3785 }

3788 return true;

3789 }

3790 return false;

3791 };

3792

3793 const APInt *C = nullptr;

3794 Value *CommonAncestor;

3795 if (MatchForward(Cond0)) {

3796

3798 CR = CR.sub(*C);

3799 if (!MatchForward(CommonAncestor))

3800 return false;

3801

3802 } else {

3803 return false;

3804 }

3805

3806

3807

3808

3809

3813}

3814

3815

3816

3817

3818

3819

3820

3821

3822

3823

3824

3825

3826

3827

3828

3829

3830

3831

3832

3833

3834

3837 Type *SelType = SI.getType();

3839

3843 const APInt *Cond1;

3844 Value *Cond0, *Ctlz, *CtlzOp;

3846 return nullptr;

3847

3851 }

3852

3853 bool ShouldDropNoWrap;

3854

3860 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp, BitWidth,

3861 ShouldDropNoWrap))

3862 return nullptr;

3863

3864 if (ShouldDropNoWrap) {

3867 }

3868

3869

3870

3871

3872

3873

3874

3876

3881 Builder.CreateAnd(Neg, ConstantInt::get(SelType, BitWidth - 1));

3884}

3885

3886

3887

3888

3889

3890

3891

3892

3893

3894

3895

3896

3898 Value *TV = SI.getTrueValue();

3899 Value *FV = SI.getFalseValue();

3900

3901 CmpPredicate Pred;

3904 return nullptr;

3905

3907 return nullptr;

3908

3909

3910

3913 return nullptr;

3916 }

3917

3920 auto FlippedPredAndConst =

3922 if (!FlippedPredAndConst)

3923 return nullptr;

3924 Pred = FlippedPredAndConst->first;

3925 RHS = FlippedPredAndConst->second;

3926 } else {

3927 return nullptr;

3928 }

3929 }

3930

3931

3932

3933

3934

3939 }

3941

3942 bool Replace = false;

3943 CmpPredicate ExtendedCmpPredicate;

3944

3945

3951 Replace = true;

3952

3953

3954

3960 Replace = true;

3961

3962

3963 CmpPredicate FalseBranchSelectPredicate;

3964 const APInt *InnerTV, *InnerFV;

3970 FalseBranchSelectPredicate =

3973 }

3974

3975 if (!InnerTV->isOne()) {

3978 }

3979

3983 Replace = true;

3984 }

3985 }

3986

3987

3989 const APInt *C;

3991 CmpPredicate InnerPred;

3992 Value *InnerRHS;

3993 const APInt *InnerTV, *InnerFV;

3997

3998

4002 bool CanSubOne = IsSigned ? C->isMinSignedValue() : C->isMinValue();

4003 if (CanSubOne) {

4004 APInt Cminus1 = *C - 1;

4006 Replace = true;

4007 }

4008 }

4009

4010

4012 InnerFV->isOne()) {

4014 bool CanAddOne = IsSigned ? C->isMaxSignedValue() : C->isMaxValue();

4015 if (CanAddOne) {

4016 APInt Cplus1 = *C + 1;

4018 Replace = true;

4019 }

4020 }

4021 }

4022 }

4023 }

4024

4025 Intrinsic::ID IID = IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;

4026 if (Replace)

4028 SI, Builder.CreateIntrinsic(SI.getType(), IID, {LHS, RHS}));

4029 return nullptr;

4030}

4031

4035

4038}

4039

4043 bool SelectIsNSZ) {

4048

4049

4052 }

4053

4054 return false;

4055}

4056

4057

4058

4060 unsigned Depth) {

4062 return false;

4063

4064

4065

4067 return true;

4068

4072 return false;

4074 }

4076 return Op->getType()->isIntOrIntVectorTy() &&

4077 hasAffectedValue(Op, Affected, Depth + 1);

4078 });

4079 }

4080

4081 return false;

4082}

4083

4084

4085

4088

4089

4091 if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())

4092 return nullptr;

4093

4094 auto TryFoldIntoAddConstant =

4097

4098

4100 return nullptr;

4101

4103 return nullptr;

4104

4106 Swapped ? X : Z, "", &SI);

4108

4111

4112

4119

4120 return NewFAdd;

4121 };

4122

4123

4124

4125

4126

4131

4132

4133

4134

4137 return TryFoldIntoAddConstant(Pred, X, Z, FAdd, C, false);

4138

4141 return TryFoldIntoAddConstant(Pred, X, Z, FAdd, C, true);

4142

4143 return nullptr;

4144}

4145

4147 Value *FalseVal,

4150

4153 return nullptr;

4154

4157 bool CreateAnd = false;

4159 Value *CmpLHS, *CmpRHS;

4160

4164 return nullptr;

4165

4166 V = CmpLHS;

4167 const APInt *AndRHS;

4169 return nullptr;

4170

4171 AndMask = *AndRHS;

4174 AndMask = Res->Mask;

4175 V = Res->X;

4179 return nullptr;

4180

4181 Pred = Res->Pred;

4182 CreateAnd = true;

4183 } else {

4184 return nullptr;

4185 }

4187 V = Trunc->getOperand(0);

4188 AndMask = APInt(V->getType()->getScalarSizeInBits(), 1);

4190 CreateAnd = !Trunc->hasNoUnsignedWrap();

4191 } else {

4192 return nullptr;

4193 }

4194

4197

4199 CreateAnd, Builder))

4200 return X;

4201

4203 CreateAnd, Builder))

4204 return X;

4205

4206 return nullptr;

4207}

4208

4210 Value *CondVal = SI.getCondition();

4213 Type *SelType = SI.getType();

4214

4216 SQ.getWithInstruction(&SI)))

4218

4219 if (Instruction *I = canonicalizeSelectToShuffle(SI))

4220 return I;

4221

4222 if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, *this))

4223 return I;

4224

4225

4226

4227

4233 true))

4235

4238 true))

4240

4245 return &SI;

4246 }

4247

4249 return R;

4250

4251

4252

4253

4254

4255

4256

4257

4258

4259

4262

4264 return new ZExtInst(CondVal, SelType);

4265

4266

4268 return new SExtInst(CondVal, SelType);

4269

4270

4272 Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());

4273 return new ZExtInst(NotCond, SelType);

4274 }

4275

4276

4278 Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());

4279 return new SExtInst(NotCond, SelType);

4280 }

4281 }

4282

4284

4287 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);

4288

4289 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||

4290 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {

4291

4292

4293

4294

4295

4298 Value *NewCond = Builder.CreateFCmpFMF(InvPred, Cmp0, Cmp1, FCmp,

4299 FCmp->getName() + ".inv");

4300

4301 FastMathFlags FMF = SI.getFastMathFlags();

4302 if (FCmp->hasNoNaNs())

4304 if (FCmp->hasNoInfs())

4307 Builder.CreateSelectFMF(NewCond, FalseVal, TrueVal, FMF);

4309 }

4310 }

4311

4312 if (SIFPOp) {

4313

4314

4315

4316

4317

4318

4319

4320

4321

4322

4323

4324

4325

4326 Value *MatchCmp0 = nullptr;

4327 Value *MatchCmp1 = nullptr;

4328

4329

4330

4337 }

4338

4339 if (Cmp0 == MatchCmp0 &&

4340 matchFMulByZeroIfResultEqZero(*this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,

4341 SI, SIFPOp->hasNoSignedZeros()))

4343 }

4344 }

4345

4346 if (SIFPOp) {

4347

4348

4350

4351

4352

4353 if (SIFPOp->hasNoNaNs() &&

4354 (SIFPOp->hasNoSignedZeros() ||

4355 (SIFPOp->hasOneUse() &&

4359 Value *BinIntr =

4360 Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, X, Y, &SI);

4362 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());

4363 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());

4364 }

4366 }

4367

4369 Value *BinIntr =

4370 Builder.CreateBinaryIntrinsic(Intrinsic::minnum, X, Y, &SI);

4372 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());

4373 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());

4374 }

4376 }

4377 }

4378 }

4379

4380

4381 if (Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *this))

4382 return Fabs;

4383

4384

4387 return NewSel;

4388

4392

4393 if (Value *V = foldSelectBitTest(SI, CondVal, TrueVal, FalseVal, Builder, SQ))

4395

4396 if (Instruction *Add = foldAddSubSelect(SI, Builder))

4397 return Add;

4398 if (Instruction *Add = foldOverflowingAddSubSelect(SI, Builder))

4399 return Add;

4401 return Or;

4403 return Mul;

4404

4405

4408 if (TI && FI && TI->getOpcode() == FI->getOpcode())

4410 return IV;

4411

4413 return I;

4414

4415 if (Instruction *I = foldSelectWithSRem(SI, *this, Builder))

4416 return I;

4417

4418

4419

4420 auto SelectGepWithBase = [&](GetElementPtrInst *Gep, Value *Base,

4421 bool Swap) -> GetElementPtrInst * {

4425 return nullptr;

4428 return nullptr;

4430 Value *NewT = Idx;

4432 if (Swap)

4435 Builder.CreateSelect(CondVal, NewT, NewF, SI.getName() + ".idx", &SI);

4438 };

4440 if (auto *NewGep = SelectGepWithBase(TrueGep, FalseVal, false))

4441 return NewGep;

4443 if (auto *NewGep = SelectGepWithBase(FalseGep, TrueVal, true))

4444 return NewGep;

4445

4446

4448 if (Instruction *FoldI = foldSelectIntoOp(SI, TrueVal, FalseVal))

4449 return FoldI;

4450

4454 auto SPF = SPR.Flavor;

4455 if (SPF) {

4456 Value *LHS2, *RHS2;

4459 RHS2, SI, SPF, RHS))

4460 return R;

4463 RHS2, SI, SPF, LHS))

4464 return R;

4465 }

4466

4468

4469

4470

4471

4472 bool IsCastNeeded = LHS->getType() != SelType;

4475 if (IsCastNeeded ||

4477 ((CmpLHS != LHS && CmpLHS != RHS) ||

4478 (CmpRHS != LHS && CmpRHS != RHS)))) {

4480

4484 else

4487

4489 if (!IsCastNeeded)

4491

4492 Value *NewCast = Builder.CreateCast(CastOp, NewSI, SelType);

4494 }

4495 }

4496 }

4497

4498

4501 return NV;

4502

4504 if (TrueSI->getCondition()->getType() == CondVal->getType()) {

4505

4506

4507 if (Value *V = simplifyNestedSelectsUsingImpliedCond(

4508 *TrueSI, CondVal, true, DL))

4510

4511

4512

4513

4514

4515 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {

4516 Value *And = Builder.CreateLogicalAnd(CondVal, TrueSI->getCondition());

4519 return &SI;

4520 }

4521 }

4522 }

4524 if (FalseSI->getCondition()->getType() == CondVal->getType()) {

4525

4526

4527 if (Value *V = simplifyNestedSelectsUsingImpliedCond(

4528 *FalseSI, CondVal, false, DL))

4530

4531

4532 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {

4533 Value *Or = Builder.CreateLogicalOr(CondVal, FalseSI->getCondition());

4536 return &SI;

4537 }

4538 }

4539 }

4540

4541

4542

4543

4544

4545

4546

4547 BinaryOperator *TrueBO;

4550 if (TrueBOSI->getCondition() == CondVal) {

4551 replaceOperand(*TrueBO, 0, TrueBOSI->getTrueValue());

4553 return &SI;

4554 }

4555 }

4557 if (TrueBOSI->getCondition() == CondVal) {

4558 replaceOperand(*TrueBO, 1, TrueBOSI->getTrueValue());

4560 return &SI;

4561 }

4562 }

4563 }

4564

4565

4566 BinaryOperator *FalseBO;

4569 if (FalseBOSI->getCondition() == CondVal) {

4570 replaceOperand(*FalseBO, 0, FalseBOSI->getFalseValue());

4572 return &SI;

4573 }

4574 }

4576 if (FalseBOSI->getCondition() == CondVal) {

4577 replaceOperand(*FalseBO, 1, FalseBOSI->getFalseValue());

4579 return &SI;

4580 }

4581 }

4582 }

4583

4588 SI.swapValues();

4589 SI.swapProfMetadata();

4590 return &SI;

4591 }

4592

4594 return I;

4595

4596

4597

4598

4599

4600

4602 KnownBits Known(1);

4608 }

4609

4610 if (Instruction *BitCastSel = foldSelectCmpBitcasts(SI, Builder))

4611 return BitCastSel;

4612

4613

4614 if (Value *V = foldSelectCmpXchg(SI))

4616

4619

4620 if (Instruction *Funnel = foldSelectFunnelShift(SI, Builder))

4621 return Funnel;

4622

4623 if (Instruction *Copysign = foldSelectToCopysign(SI, Builder))

4624 return Copysign;

4625

4626 if (Instruction *PN = foldSelectToPhi(SI, DT, Builder))

4628

4629 if (Value *V = foldRoundUpIntegerWithPow2Alignment(SI, Builder))

4631

4632 if (Value *V = foldSelectIntoAddConstant(SI, Builder))

4634

4635

4636

4644 MaskedInst->setArgOperand(2, FalseVal );

4646 }

4647

4654 (CondVal->getType() == Mask->getType())) {

4655

4656

4657

4658

4659 bool CanMergeSelectIntoLoad = false;

4661 CanMergeSelectIntoLoad = match(V, m_Zero());

4662

4663 if (CanMergeSelectIntoLoad) {

4666 MaskedInst->setArgOperand(2, TrueVal );

4668 }

4669 }

4670

4671 if (Instruction *I = foldSelectOfSymmetricSelect(SI, Builder))

4672 return I;

4673

4674 if (Instruction *I = foldNestedSelects(SI, Builder))

4675 return I;

4676

4677

4678

4679

4680

4682 return &SI;

4683

4684 if (Instruction *I = foldBitCeil(SI, Builder, *this))

4685 return I;

4686

4688 return I;

4689

4691 return I;

4692

4693

4694

4695

4696

4697

4698 auto FoldSelectWithAndOrCond = [&](bool IsAnd, Value *A,

4699 Value *B) -> Instruction * {

4701 SQ.getWithInstruction(&SI))) {

4704

4705

4706

4707

4709 if (NewTrueVal == TrueVal && NewFalseVal == FalseVal &&

4711 MDFrom = &SI;

4712 }

4714 MDFrom);

4715 }

4716

4717

4720 if (Value *V = canonicalizeSPF(*Cmp, TrueVal, FalseVal, *this))

4722 IsAnd ? FalseVal : V);

4723 }

4724

4725 return nullptr;

4726 };

4727

4730 if (Instruction *I = FoldSelectWithAndOrCond( true, LHS, RHS))

4731 return I;

4732 if (Instruction *I = FoldSelectWithAndOrCond( true, RHS, LHS))

4733 return I;

4735 if (Instruction *I = FoldSelectWithAndOrCond( false, LHS, RHS))

4736 return I;

4737 if (Instruction *I = FoldSelectWithAndOrCond( false, RHS, LHS))

4738 return I;

4739 } else {

4740

4741

4743 if (Instruction *I = FoldSelectWithAndOrCond( true, LHS, RHS))

4744 return I;

4746 if (Instruction *I = FoldSelectWithAndOrCond( false, LHS, RHS))

4747 return I;

4748 }

4749 }

4750

4751

4753 return BinaryOperator::CreateXor(CondVal, FalseVal);

4754

4755

4756

4759

4760 CondContext CC(CondVal);

4762 CC.AffectedValues.insert(V);

4763 });

4764 SimplifyQuery Q = SQ.getWithInstruction(&SI).getWithCondContext(CC);

4765 if (!CC.AffectedValues.empty()) {

4767 hasAffectedValue(TrueVal, CC.AffectedValues, 0)) {

4771 ConstantInt::get(SelType, Known.getConstant()));

4772 }

4773

4774 CC.Invert = true;

4776 hasAffectedValue(FalseVal, CC.AffectedValues, 0)) {

4780 ConstantInt::get(SelType, Known.getConstant()));

4781 }

4782 }

4783 }

4784

4785

4786

4787

4788

4791 if (TrueVal == Trunc)

4793 if (FalseVal == Trunc)

4795 }

4797 if (TrueVal == Trunc)

4800 if (FalseVal == Trunc)

4802 }

4803

4804 Value *MaskedLoadPtr;

4808 SI, Builder.CreateMaskedLoad(

4809 TrueVal->getType(), MaskedLoadPtr,

4811 CondVal, FalseVal));

4812

4813

4814

4815

4816 unsigned BitWidth = SI.getType()->getScalarSizeInBits();

4817 CmpPredicate Pred;

4818 Value *CmpLHS, *CmpRHS;

4819

4820

4821

4822

4833

4835 SI.getModule(), Intrinsic::scmp, {SI.getType(), SI.getType()});

4836 return CallInst::Create(Scmp, {CmpLHS, ConstantInt::get(SI.getType(), 0)});

4837 }

4838

4839 return nullptr;

4840}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

AMDGPU Register Bank Select

This file implements a class to represent arbitrary precision integral constant values and operations...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

This file provides internal interfaces used to implement the InstCombine.

static Value * foldSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)

Try to fold a select to a min/max intrinsic.

Definition InstCombineSelect.cpp:586

static Value * canonicalizeSaturatedAddSigned(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)

Definition InstCombineSelect.cpp:1132

static Value * canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)

Definition InstCombineSelect.cpp:1207

static Instruction * foldSetClearBits(SelectInst &Sel, InstCombiner::BuilderTy &Builder)

Canonicalize a set or clear of a masked set of constant bits to select-of-constants form.

Definition InstCombineSelect.cpp:856

static Instruction * foldSelectICmpAndAnd(Type *SelType, const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)

We want to turn: (select (icmp eq (and X, Y), 0), (and (lshr X, Z), 1), 1) into: zext (icmp ne i32 (a...

Definition InstCombineSelect.cpp:647

static unsigned getSelectFoldableOperands(BinaryOperator *I)

We want to turn code that looks like this: C = or A, B D = select cond, C, A into: C = select cond,...

Definition InstCombineSelect.cpp:226

static Value * canonicalizeSaturatedSubtract(const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)

Transform patterns such as (a > b) ?

Definition InstCombineSelect.cpp:963

static Value * foldAbsDiff(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)

Try to match patterns with select and subtract as absolute difference.

Definition InstCombineSelect.cpp:1222

static Instruction * foldSelectZeroOrFixedOp(SelectInst &SI, InstCombinerImpl &IC)

Definition InstCombineSelect.cpp:899

static Instruction * foldSelectBinOpIdentity(SelectInst &Sel, const TargetLibraryInfo &TLI, InstCombinerImpl &IC)

Replace a select operand based on an equality comparison with the identity constant of a binop.

Definition InstCombineSelect.cpp:61

static Value * foldSelectICmpAnd(SelectInst &Sel, Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, InstCombiner::BuilderTy &Builder)

This folds: select (icmp eq (and X, C1)), TC, FC iff C1 is a power 2 and the difference between TC an...

Definition InstCombineSelect.cpp:128

static Value * foldSelectICmpAndZeroShl(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)

We want to turn: (select (icmp eq (and X, C1), 0), 0, (shl [nsw/nuw] X, C2)); iff C1 is a mask and th...

Definition InstCombineSelect.cpp:695

static Value * canonicalizeSaturatedAddUnsigned(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)

Definition InstCombineSelect.cpp:1031

static Value * foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)

We want to turn: (select (icmp sgt x, C), lshr (X, Y), ashr (X, Y)); iff C s>= -1 (select (icmp slt x...

Definition InstCombineSelect.cpp:733

static bool isSelect01(const APInt &C1I, const APInt &C2I)

Definition InstCombineSelect.cpp:492

static Value * foldSelectICmpAndBinOp(Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, InstCombiner::BuilderTy &Builder)

We want to turn: (select (icmp eq (and X, C1), 0), Y, (BinOp Y, C2)) into: IF C2 u>= C1 (BinOp Y,...

Definition InstCombineSelect.cpp:788

This file provides the interface for the instcombine pass implementation.

Machine Check Debug Module

uint64_t IntrinsicInst * II

const SmallVectorImpl< MachineOperand > & Cond

This file defines the SmallVector class.

static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

static const uint32_t IV[8]

bool bitwiseIsEqual(const APFloat &RHS) const

Class for arbitrary precision integers.

static APInt getAllOnes(unsigned numBits)

Return an APInt of a specified width with all bits set.

static APInt getSignMask(unsigned BitWidth)

Get the SignMask for a specific bit width.

bool isMinSignedValue() const

Determine if this is the smallest signed value.

uint64_t getZExtValue() const

Get zero extended value.

bool isAllOnes() const

Determine if all bits are set. This is true for zero-width values.

bool isZero() const

Determine if this value is zero, i.e. all bits are clear.

unsigned getBitWidth() const

Return the number of bits in the APInt.

static APInt getSignedMaxValue(unsigned numBits)

Gets maximum signed value of APInt for a specific bit width.

bool isMinValue() const

Determine if this is the smallest unsigned value.

static APInt getSignedMinValue(unsigned numBits)

Gets minimum signed value of APInt for a specific bit width.

unsigned countLeadingZeros() const

unsigned logBase2() const

bool isMask(unsigned numBits) const

bool isMaxSignedValue() const

Determine if this is the largest signed value.

bool isNonNegative() const

Determine if this APInt Value is non-negative (>= 0)

bool isPowerOf2() const

Check if this APInt's value is a power of two greater than zero.

static APInt getZero(unsigned numBits)

Get the '0' value for the specified bit-width.

bool isOne() const

Determine if this is a value of 1.

bool isMaxValue() const

Determine if this is the largest unsigned value.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

An instruction that atomically checks whether a specified value is in a memory location,...

LLVM Basic Block Representation.

iterator begin()

Instruction iterator methods.

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

BinaryOps getOpcode() const

static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)

static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)

Construct a binary instruction, given the opcode and the two operands.

This class represents a no-op cast from one type to another.

This class represents a function call, abstracting a target machine's calling convention.

static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...

This class is the base class for the comparison instructions.

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ FCMP_OEQ

0 0 0 1 True if ordered and equal

@ ICMP_SLT

signed less than

@ ICMP_SLE

signed less or equal

@ FCMP_OLT

0 1 0 0 True if ordered and less than

@ FCMP_ULE

1 1 0 1 True if unordered, less than, or equal

@ FCMP_OGT

0 0 1 0 True if ordered and greater than

@ FCMP_OGE

0 0 1 1 True if ordered and greater than or equal

@ ICMP_UGE

unsigned greater or equal

@ ICMP_UGT

unsigned greater than

@ ICMP_SGT

signed greater than

@ FCMP_ULT

1 1 0 0 True if unordered or less than

@ FCMP_ONE

0 1 1 0 True if ordered and operands are unequal

@ FCMP_UEQ

1 0 0 1 True if unordered or equal

@ ICMP_ULT

unsigned less than

@ FCMP_UGT

1 0 1 0 True if unordered or greater than

@ FCMP_OLE

0 1 0 1 True if ordered and less than or equal

@ ICMP_SGE

signed greater or equal

@ FCMP_UNE

1 1 1 0 True if unordered or not equal

@ ICMP_ULE

unsigned less or equal

@ FCMP_UGE

1 0 1 1 True if unordered, greater than, or equal

Predicate getSwappedPredicate() const

For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.

static bool isFPPredicate(Predicate P)

bool isNonStrictPredicate() const

static bool isRelational(Predicate P)

Return true if the predicate is relational (not EQ or NE).

Predicate getInversePredicate() const

For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...

Predicate getPredicate() const

Return the predicate for this instruction.

static LLVM_ABI bool isUnordered(Predicate predicate)

Determine if the predicate is an unordered operation.

Predicate getFlippedStrictnessPredicate() const

For predicate of kind "is X or equal to 0" returns the predicate "is X".

bool isIntPredicate() const

static LLVM_ABI bool isOrdered(Predicate predicate)

Determine if the predicate is an ordered operation.

An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...

static LLVM_ABI std::optional< CmpPredicate > getMatching(CmpPredicate A, CmpPredicate B)

Compares two CmpPredicates taking samesign into account and returns the canonicalized CmpPredicate if...

static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)

static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)

Return the identity constant for a binary opcode.

static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)

static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)

static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)

This class represents a range of values.

LLVM_ABI ConstantRange add(const ConstantRange &Other) const

Return a new range representing the possible values resulting from an addition of a value in this ran...

LLVM_ABI bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const

Does the predicate Pred hold between ranges this and Other?

static LLVM_ABI ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)

Compute range of intrinsic result for the given operand ranges.

static LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)

Produce the exact range such that all values in the returned range satisfy the given predicate with a...

LLVM_ABI ConstantRange binaryNot() const

Return a new range representing the possible values resulting from a binary-xor of a value in this ra...

LLVM_ABI ConstantRange binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const

Return a new range representing the possible values resulting from an application of the specified bi...

LLVM_ABI ConstantRange sub(const ConstantRange &Other) const

Return a new range representing the possible values resulting from a subtraction of a value in this r...

This is an important base class in LLVM.

static LLVM_ABI Constant * mergeUndefsWith(Constant *C, Constant *Other)

Merges undefs of a Constant with another Constant, along with the undefs already present.

static LLVM_ABI Constant * getAllOnesValue(Type *Ty)

LLVM_ABI bool isOneValue() const

Returns true if the value is one.

static LLVM_ABI Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

LLVM_ABI Constant * getAggregateElement(unsigned Elt) const

For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...

LLVM_ABI bool isNullValue() const

Return true if this is the value that would be returned by getNullValue.

A parsed version of the target data layout string in and methods for querying it.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const

Return true if the (end of the) basic block BB dominates the use U.

Tagged union holding either a T or a Error.

Utility class for floating point operations which can have information about relaxed accuracy require...

FastMathFlags getFastMathFlags() const

Convenience function for getting all the fast-math flags.

Convenience struct for specifying and reasoning about fast-math flags.

static FastMathFlags intersectRewrite(FastMathFlags LHS, FastMathFlags RHS)

Intersect rewrite-based flags.

bool noSignedZeros() const

static FastMathFlags unionValue(FastMathFlags LHS, FastMathFlags RHS)

Union value flags.

void setNoSignedZeros(bool B=true)

void setNoNaNs(bool B=true)

void setNoInfs(bool B=true)

This class represents a freeze function that returns random concrete value if an operand is either a ...

Value * getPointerOperand()

static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

Type * getSourceElementType() const

LLVM_ABI GEPNoWrapFlags getNoWrapFlags() const

Get the nowrap flags for the GEP instruction.

This instruction compares its operands according to the predicate given to the constructor.

static CmpPredicate getSwappedCmpPredicate(CmpPredicate Pred)

static bool isLT(Predicate P)

Return true if the predicate is SLT or ULT.

CmpPredicate getInverseCmpPredicate() const

static bool isGT(Predicate P)

Return true if the predicate is SGT or UGT.

static CmpPredicate getInverseCmpPredicate(CmpPredicate Pred)

static bool isEquality(Predicate P)

Return true if this predicate is either EQ or NE.

bool isRelational() const

Return true if the predicate is relational (not EQ or NE).

Common base class shared among various IRBuilders.

Value * CreateFAdd(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)

LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")

Return a vector value that contains.

Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")

LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)

Value * CreateFreeze(Value *V, const Twine &Name="")

Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)

LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")

Create a call to intrinsic ID with 2 operands which is mangled on the first type.

PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")

LLVM_ABI CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, FMFSource FMFSource={}, const Twine &Name="")

Create a call to intrinsic ID with 1 operand which is mangled on its type.

Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)

Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")

Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)

ConstantInt * getFalse()

Get the constant value for i1 false.

Value * CreateIsNotNull(Value *Arg, const Twine &Name="")

Return a boolean value testing if Arg != 0.

Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)

Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")

void SetInsertPoint(BasicBlock *TheBB)

This specifies that created instructions should be appended to the end of the specified block.

Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")

Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")

Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)

Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)

Instruction * foldSelectToCmp(SelectInst &SI)

bool fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF, const Instruction *CtxI) const

Check if fmul MulVal, +0.0 will yield +0.0 (or signed zero is ignorable).

KnownFPClass computeKnownFPClass(Value *Val, FastMathFlags FMF, FPClassTest Interested=fcAllFlags, const Instruction *CtxI=nullptr, unsigned Depth=0) const

Instruction * foldSelectEqualityTest(SelectInst &SI)

Instruction * foldSelectValueEquivalence(SelectInst &SI, CmpInst &CI)

Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)

Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...

Instruction * foldVectorSelect(SelectInst &Sel)

Value * SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &PoisonElts, unsigned Depth=0, bool AllowMultipleUsers=false) override

The specified value produces a vector with any number of elements.

Instruction * foldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, Instruction &Outer, SelectPatternFlavor SPF2, Value *C)

Instruction * foldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI)

We have (select c, TI, FI), and we know that TI and FI have the same opcode.

Definition InstCombineSelect.cpp:249

bool replaceInInstruction(Value *V, Value *Old, Value *New, unsigned Depth=0)

Instruction * foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI)

bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)

Instruction * foldSelectIntoOp(SelectInst &SI, Value *, Value *)

Try to fold the select into one of the operands to allow further optimization.

Definition InstCombineSelect.cpp:500

Value * foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal, Value *FalseVal)

Instruction * visitSelectInst(SelectInst &SI)

Instruction * foldSelectOfBools(SelectInst &SI)

Instruction * foldSelectExtConst(SelectInst &Sel)

The core instruction combiner logic.

const DataLayout & getDataLayout() const

IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy

An IRBuilder that automatically inserts new instructions into the worklist.

Instruction * InsertNewInstBefore(Instruction *New, BasicBlock::iterator Old)

Inserts an instruction New before instruction Old.

Instruction * replaceInstUsesWith(Instruction &I, Value *V)

A combiner-aware RAUW-like routine.

static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI)

void replaceUse(Use &U, Value *NewValue)

Replace use and add the previously used value to the worklist.

static bool isCanonicalPredicate(CmpPredicate Pred)

Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...

InstructionWorklist & Worklist

A worklist of the instructions that need to be simplified.

void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const

void addToWorklist(Instruction *I)

Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)

Replace operand of instruction and add old operand to the worklist.

Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)

const SimplifyQuery & getSimplifyQuery() const

static Constant * AddOne(Constant *C)

Add one to a Constant.

bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)

LLVM_ABI bool hasNoNaNs() const LLVM_READONLY

Determine whether the no-NaNs flag is set.

LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY

Determine whether the no unsigned wrap flag is set.

LLVM_ABI bool hasNoInfs() const LLVM_READONLY

Determine whether the no-infs flag is set.

LLVM_ABI bool isSameOperationAs(const Instruction *I, unsigned flags=0) const LLVM_READONLY

This function determines if the specified instruction executes the same operation as the current one.

LLVM_ABI void setHasNoSignedZeros(bool B)

Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...

LLVM_ABI bool hasNoSignedZeros() const LLVM_READONLY

Determine whether the no-signed-zeros flag is set.

LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY

Determine whether the no signed wrap flag is set.

LLVM_ABI void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)

Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...

LLVM_ABI const Module * getModule() const

Return the module owning the function this instruction belongs to or nullptr it the function does not...

LLVM_ABI void andIRFlags(const Value *V)

Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.

LLVM_ABI void setHasNoNaNs(bool B)

Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...

LLVM_ABI bool isCommutative() const LLVM_READONLY

Return true if the instruction is commutative:

LLVM_ABI void setFastMathFlags(FastMathFlags FMF)

Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...

LLVM_ABI void swapProfMetadata()

If the instruction has "branch_weights" MD_prof metadata and the MDNode has three operands (including...

LLVM_ABI void setHasNoInfs(bool B)

Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...

LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY

Convenience function for getting all the fast-math flags, which must be an operator which supports th...

unsigned getOpcode() const

Returns a member of one of the enums like Instruction::Add.

LLVM_ABI const DataLayout & getDataLayout() const

Get the data layout of the module this instruction belongs to.

A wrapper class for inspecting calls to intrinsic functions.

void addIncoming(Value *V, BasicBlock *BB)

Add an incoming value to the end of the PHI list.

This class represents a sign extension of integer types.

This class represents the LLVM 'select' instruction.

const Value * getFalseValue() const

void swapValues()

Swap the true and false values of the select instruction.

const Value * getCondition() const

static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)

const Value * getTrueValue() const

bool insert(const value_type &X)

Insert a new element into the SetVector.

This instruction constructs a fixed permutation of two input vectors.

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

bool contains(ConstPtrType Ptr) const

A SetVector that performs no allocations if smaller than a certain size.

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

Provides information about what library functions are available for the current target.

The instances of the Type class are immutable: once they are created, they are never changed.

bool isVectorTy() const

True if this is an instance of VectorType.

bool isIntOrIntVectorTy() const

Return true if this is an integer type or a vector of integer types.

LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY

If this is a vector type, return the getPrimitiveSizeInBits value for the element type.

static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)

bool isPtrOrPtrVectorTy() const

Return true if this is a pointer type or a vector of pointer types.

bool isIntegerTy() const

True if this is an instance of IntegerType.

bool isFPOrFPVectorTy() const

Return true if this is a FP type or a vector of FP.

static UnaryOperator * CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Value * getOperand(unsigned i) const

unsigned getNumOperands() const

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

LLVM_ABI const Value * DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const

Translate PHI node to its predecessor from the given basic block.

bool hasOneUse() const

Return true if there is exactly one use of this value.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

LLVM_ABI void takeName(Value *V)

Transfer the name from V to this value.

Represents an op.with.overflow intrinsic.

This class represents zero extension of integer types.

const ParentTy * getParent() const

self_iterator getIterator()

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr std::underlying_type_t< E > Mask()

Get a bitmask with 1s in all places up to the high-order bit of E's largest value.

@ C

The default llvm calling convention, compatible with C.

int getMinValue(MCInstrInfo const &MCII, MCInst const &MCI)

Return the minimum value of an extendable operand.

int getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI)

Return the maximum value of an extendable operand.

LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})

Look up the Function declaration of the intrinsic id in the Module M.

BinaryOpc_match< LHS, RHS, false > m_BinOp(unsigned Opcode, const LHS &L, const RHS &R)

SpecificConstantMatch m_ZeroInt()

Convenience matchers for specific integer values.

BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)

Matches a register negated by a G_SUB.

BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)

Matches a register not-ed by a G_XOR.

OneUse_match< SubPat > m_OneUse(const SubPat &SP)

Predicate

Predicate - These are "(BI << 5) | BO" for various predicates.

cst_pred_ty< is_all_ones > m_AllOnes()

Match an integer or vector with all bits set.

BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)

BinaryOp_match< cst_pred_ty< is_all_ones, false >, ValTy, Instruction::Xor, true > m_NotForbidPoison(const ValTy &V)

BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)

class_match< BinaryOperator > m_BinOp()

Match an arbitrary binary operation and ignore it.

CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::FMul, true > m_c_FMul(const LHS &L, const RHS &R)

Matches FMul with LHS and RHS in either order.

cst_pred_ty< is_sign_mask > m_SignMask()

Match an integer or vector with only the sign bit(s) set.

OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)

cst_pred_ty< is_power2 > m_Power2()

Match an integer or vector power-of-2.

match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)

CommutativeBinaryIntrinsic_match< IntrID, T0, T1 > m_c_Intrinsic(const T0 &Op0, const T1 &Op1)

class_match< Constant > m_Constant()

Match an arbitrary Constant and ignore it.

ap_match< APInt > m_APInt(const APInt *&Res)

Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.

BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)

Matches an And with LHS and RHS in either order.

CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)

Matches Trunc.

BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)

ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)

Match APInt while allowing poison in splat vector constants.

LogicalOp_match< LHS, RHS, Instruction::And > m_LogicalAnd(const LHS &L, const RHS &R)

Matches L && R either in the form of L & R or L ?

OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)

specific_intval< false > m_SpecificInt(const APInt &V)

Match a specific integer value or vector with all elements equal to the value.

match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)

bool match(Val *V, const Pattern &P)

BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)

Matches integer division operations.

bind_ty< Instruction > m_Instruction(Instruction *&I)

Match an instruction, capturing it if we match.

cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()

Match a floating-point negative zero or positive zero.

specificval_ty m_Specific(const Value *V)

Match if we have a specific specified value.

constantexpr_match m_ConstantExpr()

Match a constant expression or a constant that contains a constant expression.

specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)

ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)

Match APFloat while allowing poison in splat vector constants.

CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)

Matches an ICmp with a predicate over LHS and RHS in either order.

OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)

Matches a 'Neg' as 'sub nsw 0, V'.

m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedLoad(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)

Matches MaskedLoad Intrinsic.

TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)

Matches ExtractElementInst.

class_match< ConstantInt > m_ConstantInt()

Match an arbitrary ConstantInt and ignore it.

cst_pred_ty< is_one > m_One()

Match an integer 1 or a vector with all elements equal to 1.

IntrinsicID_match m_Intrinsic()

Match intrinsic calls like this: m_IntrinsicIntrinsic::fabs(m_Value(X))

ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)

Matches SelectInst.

match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmin_pred_ty > > m_OrdOrUnordFMin(const LHS &L, const RHS &R)

Match an 'ordered' or 'unordered' floating point minimum function.

ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)

Match a single index ExtractValue instruction.

BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)

Matches logical shift operations.

match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)

Combine two pattern matchers matching L && R.

MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)

cst_pred_ty< is_any_apint > m_AnyIntegralConstant()

Match an integer or vector with any integral constant.

bind_ty< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)

Match a with overflow intrinsic, capturing it if we match.

BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)

Matches an Xor with LHS and RHS in either order.

BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)

deferredval_ty< Value > m_Deferred(Value *const &V)

Like m_Specific(), but works if the specific value to match is determined as part of the same match()...

NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)

Matches trunc nsw.

auto m_LogicalOr()

Matches L || R where L and R are arbitrary values.

TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)

Matches ShuffleVectorInst independently of mask value.

ap_match< APInt > m_APIntForbidPoison(const APInt *&Res)

Match APInt while forbidding poison in splat vector constants.

cst_pred_ty< is_strictlypositive > m_StrictlyPositive()

Match an integer or vector of strictly positive values.

SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)

CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)

Matches ZExt.

MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)

class_match< CmpInst > m_Cmp()

Matches any compare instruction and ignore it.

brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)

match_immconstant_ty m_ImmConstant()

Match an arbitrary immediate Constant and ignore it.

auto m_c_LogicalOp(const LHS &L, const RHS &R)

Matches either L && R or L || R with LHS and RHS in either order.

NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)

Matches trunc nuw.

BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)

Matches a Add with LHS and RHS in either order.

m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedGather(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)

Matches MaskedGather Intrinsic.

match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmax_pred_ty > > m_OrdOrUnordFMax(const LHS &L, const RHS &R)

Match an 'ordered' or 'unordered' floating point maximum function.

CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)

Matches BitCast.

m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)

MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)

cst_pred_ty< is_maxsignedvalue > m_MaxSignedValue()

Match an integer or vector with values having all bits except for the high bit set (0x7f....

class_match< Value > m_Value()

Match an arbitrary value and ignore it.

AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)

Matches a BinaryOperator with LHS and RHS in either order.

OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)

CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)

FNeg_match< OpTy > m_FNeg(const OpTy &X)

Match 'fneg X' as 'fsub -0.0, X'.

cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()

Match a floating-point positive zero.

LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)

Matches L && R with LHS and RHS in either order.

BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)

m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)

BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)

Matches integer remainder operations.

auto m_LogicalAnd()

Matches L && R where L and R are arbitrary values.

match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > > > m_MaxOrMin(const LHS &L, const RHS &R)

m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)

class_match< BasicBlock > m_BasicBlock()

Match an arbitrary basic block value and ignore it.

BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)

auto m_Undef()

Match an arbitrary undef constant.

BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)

CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)

Matches SExt.

is_zero m_Zero()

Match any null constant or a vector with all elements equal to 0.

BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)

Matches an Or with LHS and RHS in either order.

LogicalOp_match< LHS, RHS, Instruction::Or, true > m_c_LogicalOr(const LHS &L, const RHS &R)

Matches L || R with LHS and RHS in either order.

SpecificCmpClass_match< LHS, RHS, ICmpInst, true > m_c_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)

ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)

BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)

Matches a Mul with LHS and RHS in either order.

MatchFunctor< Val, Pattern > match_fn(const Pattern &P)

A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.

BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)

MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)

match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)

Combine two pattern matchers matching L || R.

cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)

Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.

ElementType

The element type of an SRV or UAV resource.

DiagnosticInfoOptimizationBase::Argument NV

NodeAddr< UseNode * > Use

friend class Instruction

Iterator for Instructions in a `BasicBlock.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

LLVM_ABI Constant * ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS, Constant *RHS, Type *Ty, Instruction *FMFSource)

LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)

Given an exploded icmp instruction, return true if the comparison only checks the sign bit.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

APFloat abs(APFloat X)

Returns the absolute value of the argument.

LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)

Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.

LLVM_ABI CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)

Return the canonical comparison predicate for the specified minimum/maximum flavor.

LLVM_ABI bool canIgnoreSignBitOfZero(const Use &U)

Return true if the sign bit of the FP value can be ignored by the user when the value is zero.

LLVM_ABI bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)

Returns true if V cannot be undef, but may be poison.

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)

Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...

constexpr unsigned MaxAnalysisRecursionDepth

SelectPatternFlavor

Specific patterns of select instructions we can match.

@ SPF_ABS

Floating point maxnum.

@ SPF_NABS

Absolute value.

constexpr bool isPowerOf2_32(uint32_t Value)

Return true if the argument is a power of two > 0.

LLVM_ABI bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)

Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...

LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)

Return true if V is poison given that ValAssumedPoison is already poison.

LLVM_ABI SelectPatternResult getSelectPattern(CmpInst::Predicate Pred, SelectPatternNaNBehavior NaNBehavior=SPNB_NA, bool Ordered=false)

Determine the pattern for predicate X Pred Y ? X : Y.

LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)

Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...

LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)

Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...

LLVM_ABI bool cannotBeNegativeZero(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if we can prove that the specified FP value is never equal to -0.0.

bool none_of(R &&Range, UnaryPredicate P)

Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.

FunctionAddr VTableAddr Count

LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)

Attempt to constant fold a cast with the specified operand.

LLVM_ABI Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an And, fold the result or return null.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

LLVM_ABI bool isKnownInversion(const Value *X, const Value *Y)

Return true iff:

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI bool isNotCrossLaneOperation(const Instruction *I)

Return true if the instruction doesn't potentially cross vector lanes.

LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)

Attempt to constant fold a binary operation with the specified operands.

LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)

Return true if the given value is known to be non-zero when defined.

constexpr int PoisonMaskElem

LLVM_ABI Intrinsic::ID getMinMaxIntrinsic(SelectPatternFlavor SPF)

Convert given SPF to equivalent min/max intrinsic.

LLVM_ABI SelectPatternResult matchDecomposedSelectPattern(CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, FastMathFlags FMF=FastMathFlags(), Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)

Determine the pattern that a select with the given compare as its predicate and given values as its t...

@ Or

Bitwise or logical OR of integers.

@ Mul

Product of integers.

@ Xor

Bitwise or logical XOR of integers.

@ And

Bitwise or logical AND of integers.

DWARFExpression::Operation Op

bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)

Don't use information from its non-constant operands.

constexpr unsigned BitWidth

LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)

Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...

LLVM_ABI Value * simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags=nullptr)

See if V simplifies when its operand Op is replaced with RepOp.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...

auto predecessors(const MachineBasicBlock *BB)

LLVM_ABI std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)

Convert an integer comparison with a constant RHS into an equivalent form with the strictness flipped...

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

cl::opt< bool > ProfcheckDisableMetadataFixes("profcheck-disable-metadata-fixes", cl::Hidden, cl::init(false), cl::desc("Disable metadata propagation fixes discovered through Issue #147390"))

LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)

Returns true if V cannot be poison, but may be undef.

bool isCheckForZeroAndMulWithOverflow(Value *Op0, Value *Op1, bool IsAnd, Use *&Y)

Match one of the patterns up to the select/logic op: Op0 = icmp ne i4 X, 0 Agg = call { i4,...

LLVM_ABI Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)

Given operands for a SelectInst, fold the result or return null.

LLVM_ABI std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)

Return true if RHS is known to be implied true by LHS.

std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)

Decompose an icmp into the form ((X & Mask) pred C) if possible.

LLVM_ABI bool canIgnoreSignBitOfNaN(const Use &U)

Return true if the sign bit of the FP value can be ignored by the user when the value is NaN.

LLVM_ABI void findValuesAffectedByCondition(Value *Cond, bool IsAssume, function_ref< void(Value *)> InsertAffected)

Call InsertAffected on all Values whose known bits / value may be affected by the condition Cond.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...

bool isConstant() const

Returns true if we know the value of all bits.

APInt getMaxValue() const

Return the maximal unsigned value possible given these KnownBits.

const APInt & getConstant() const

Returns the value when all bits have a known value.

bool isKnownNeverInfinity() const

Return true if it's known this can never be an infinity.

bool isKnownNeverNaN() const

Return true if it's known this can never be a nan.

bool signBitIsZeroOrNaN() const

Return true if the sign bit must be 0, ignoring the sign of nans.

SelectPatternFlavor Flavor

bool Ordered

Only applicable if Flavor is SPF_FMINNUM or SPF_FMAXNUM.

static bool isMinOrMax(SelectPatternFlavor SPF)

When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?

SimplifyQuery getWithInstruction(const Instruction *I) const