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

1

2

3

4

5

6

7

8

9

10

11

12

13

36#include

37

38#define DEBUG_TYPE "instcombine"

40

41using namespace llvm;

42using namespace PatternMatch;

43

44

45

46

49

50

51

52 if (!V->hasOneUse()) return nullptr;

53

54 bool MadeChange = false;

55

56

57

58 Value *A = nullptr, *B = nullptr, *One = nullptr;

63 }

64

65

66

68 if (I && I->isLogicalShift() &&

70

71

74 MadeChange = true;

75 }

76

77 if (I->getOpcode() == Instruction::LShr && I->isExact()) {

78 I->setIsExact();

79 MadeChange = true;

80 }

81

82 if (I->getOpcode() == Instruction::Shl && I->hasNoUnsignedWrap()) {

83 I->setHasNoUnsignedWrap();

84 MadeChange = true;

85 }

86 }

87

88

89

90

91

92 return MadeChange ? V : nullptr;

93}

94

95

96

97

98

99

103

104

105

108 bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap();

109 Value *Neg = Builder.CreateNeg(OtherOp, "", HasAnyNoWrap);

111 }

112

113

116 bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap();

117 Value *Neg = Builder.CreateNeg(OtherOp, "", HasAnyNoWrap);

119 }

120

121

122

128

129

130

135 OtherOp, &I);

136

137 return nullptr;

138}

139

140

141

145 if (CommuteOperands)

147

150

151

154 bool PropagateNSW = HasNSW && cast(Y)->hasNoSignedWrap();

156 }

157

158

159

160

161

169 Value *Shl = Builder.CreateShl(FrX, Z, "mulshl", HasNUW, PropagateNSW);

171 }

172

173

174

175

176

177

184 }

185

186 return nullptr;

187}

188

190 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

192 simplifyMulInst(Op0, Op1, I.hasNoSignedWrap(), I.hasNoUnsignedWrap(),

195

197 return &I;

198

200 return X;

201

203 return Phi;

204

207

208 Type *Ty = I.getType();

210 const bool HasNSW = I.hasNoSignedWrap();

211 const bool HasNUW = I.hasNoUnsignedWrap();

212

213

217 }

218

219

220 {

223 const APInt *IVal;

227

230 assert(Shl && "Constant folding of immediate constants failed");

232 BinaryOperator *BO = BinaryOperator::CreateMul(NewOp, Shl);

233 if (HasNUW && Mul->hasNoUnsignedWrap())

237 return BO;

238 }

239

241

243 BinaryOperator *Shl = BinaryOperator::CreateShl(NewOp, NewCst);

244

245 if (HasNUW)

247 if (HasNSW) {

249 if (match(NewCst, m_APInt(V)) && *V != V->getBitWidth() - 1)

251 }

252

253 return Shl;

254 }

255 }

256 }

257

259

260

261 if (Value *NegOp0 =

262 Negator::Negate( true, HasNSW, Op0, *this)) {

263 auto *Op1C = cast(Op1);

266 false,

267 HasNSW && Op1C->isNotMinSignedValue()));

268 }

269

270

271

272

273

274

275

276 const APInt *NegPow2C;

280 unsigned SrcWidth = X->getType()->getScalarSizeInBits();

281 unsigned ShiftAmt = NegPow2C->countr_zero();

282 if (ShiftAmt >= BitWidth - SrcWidth) {

285 return BinaryOperator::CreateShl(Z, ConstantInt::get(Ty, ShiftAmt));

286 }

287 }

288 }

289

291 return FoldedMul;

292

295

296

299

300

304

306 auto *BOp0 = cast(Op0);

307 bool Op0NUW =

308 (BOp0->getOpcode() == Instruction::Or || BOp0->hasNoUnsignedWrap());

310 auto *BO = BinaryOperator::CreateAdd(NewMul, NewC);

311 if (HasNUW && Op0NUW) {

312

313 if (auto *NewMulBO = dyn_cast(NewMul))

314 NewMulBO->setHasNoUnsignedWrap();

315 BO->setHasNoUnsignedWrap();

316 }

317 return BO;

318 }

319 }

320

321

323 if (Op0 == Op1 && match(Op0, m_IntrinsicIntrinsic::abs(m_Value(X))))

324 return BinaryOperator::CreateMul(X, X);

325

326 {

328

329 if (I.hasNoSignedWrap() &&

337 }

338

339

344

345

347 auto *NewMul = BinaryOperator::CreateMul(X, Y);

348 if (HasNSW && cast(Op0)->hasNoSignedWrap() &&

350 NewMul->setHasNoSignedWrap();

351 return NewMul;

352 }

353

354

355

358

359

360

363 return BinaryOperator::CreateMul(NegOp0, X);

364 }

365

367

368

369

371 auto UDivCheck = [&C1](const APInt &C) { return C.urem(*C1).isZero(); };

372 auto SDivCheck = [&C1](const APInt &C) {

376 };

380 auto BOpc = cast(Op0)->getOpcode();

382 BOpc, X,

384 Op1));

385 }

386 }

387

388

389

390 {

393 if (!Div || (Div->getOpcode() != Instruction::UDiv &&

394 Div->getOpcode() != Instruction::SDiv)) {

395 Y = Op0;

396 Div = dyn_cast(Op1);

397 }

398 Value *Neg = dyn_castNegVal(Y);

401 (Div->getOpcode() == Instruction::UDiv ||

402 Div->getOpcode() == Instruction::SDiv)) {

404

405

407 if (DivOp1 == Y)

410 }

411

412 auto RemOpc = Div->getOpcode() == Instruction::UDiv ? Instruction::URem

413 : Instruction::SRem;

414

419 if (DivOp1 == Y)

420 return BinaryOperator::CreateSub(XFreeze, Rem);

421 return BinaryOperator::CreateSub(Rem, XFreeze);

422 }

423 }

424

425

426

427

428

429

433 return BinaryOperator::CreateAnd(Op0, Op1);

434

439

440

441

442

445 X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType() &&

446 (Op0->hasOneUse() || Op1->hasOneUse() || X == Y)) {

449 }

450

451

452

455 X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType() &&

456 (Op0->hasOneUse() || Op1->hasOneUse())) {

459 }

460

461

462

467

468

469

471 X->getType()->isIntOrIntVectorTy(1))

474

477

481 }

482

483

486 *C == C->getBitWidth() - 1) {

490 }

491 }

492

493

494

495

498 *C == C->getBitWidth() - 1) {

501 }

502

503

507 }

508

509

510

519 }

520

521 if (Instruction *Ext = narrowMathIfNoOverflow(I))

522 return Ext;

523

525 return Res;

526

527

528

529

530

531

532 if (Value *Res = tryGetLog2(Op0, false)) {

533 BinaryOperator *Shl = BinaryOperator::CreateShl(Op1, Res);

534

536 return Shl;

537 }

538 if (Value *Res = tryGetLog2(Op1, false)) {

539 BinaryOperator *Shl = BinaryOperator::CreateShl(Op0, Res);

540

542 return Shl;

543 }

544

545 bool Changed = false;

546 if (!HasNSW && willNotOverflowSignedMul(Op0, Op1, I)) {

547 Changed = true;

548 I.setHasNoSignedWrap(true);

549 }

550

551 if (!HasNUW && willNotOverflowUnsignedMul(Op0, Op1, I, I.hasNoSignedWrap())) {

552 Changed = true;

553 I.setHasNoUnsignedWrap(true);

554 }

555

556 return Changed ? &I : nullptr;

557}

558

561 assert((Opcode == Instruction::FMul || Opcode == Instruction::FDiv) &&

562 "Expected fmul or fdiv");

563

564 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

566

567

568

571

572

573

576

577

578

580 (Op0->hasOneUse() || Op1->hasOneUse())) {

585 }

586

587 return nullptr;

588}

589

596 Intrinsic::powi, {X->getType(), YZ->getType()}, {X, YZ}, &I);

597

598 return NewPow;

599 };

600

602 unsigned Opcode = I.getOpcode();

603 assert((Opcode == Instruction::FMul || Opcode == Instruction::FDiv) &&

604 "Unexpected opcode");

605

606

607

611 Constant *One = ConstantInt::get(Y->getType(), 1);

612 if (willNotOverflowSignedAdd(Y, One, I)) {

613 Instruction *NewPow = createPowiExpr(I, *this, X, Y, One);

615 }

616 }

617

618

619 Value *Op0 = I.getOperand(0);

620 Value *Op1 = I.getOperand(1);

621 if (Opcode == Instruction::FMul && I.isOnlyUserOfAnyOperand() &&

626 Y->getType() == Z->getType()) {

627 Instruction *NewPow = createPowiExpr(I, *this, X, Y, Z);

629 }

630

631 if (Opcode == Instruction::FDiv && I.hasAllowReassoc() && I.hasNoNaNs()) {

632

633

634

635

638 willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) {

640 Instruction *NewPow = createPowiExpr(I, *this, Op1, Y, NegOne);

642 }

643

644

645

646

647

651 willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) {

653 auto *NewPow = createPowiExpr(I, *this, X, Y, NegOne);

655 }

656 }

657

658 return nullptr;

659}

660

661

662

663

664

665

676 }

677

682 R2.insert(I);

683 }

684 }

685 return !R1.empty() && R2.empty();

686}

687

688

689

690

691

692

693

694

695

696

697

698

702

704 return false;

705

709

710 CallInst *FSqrt = cast(X->getOperand(1));

713 return false;

714

715

716

717

718

719 if (X->hasAllowReassoc() || X->hasAllowReciprocal() || X->hasNoInfs())

720 return false;

721

722

723

724

725

726 if (BBx != BBr1 && BBx != BBr2)

727 return false;

728

729

731

732

733

734

735 return (I->getParent() != BBr1 || I->hasAllowReassoc());

736 }))

737 return false;

738

739

741

742

743

744

745 return (I->getParent() == BBr2 && I->hasAllowReassoc());

746 });

747}

748

750 Value *Op0 = I.getOperand(0);

751 Value *Op1 = I.getOperand(1);

755

756

757

760

764

769 }

771

772

777

778

779

784 }

785

786

787

788

790

795 }

796 }

798

803 }

804 }

805 }

806

811 BinaryOperator *DivOp = cast(((Z == Op0) ? Op1 : Op0));

814

817 }

818 }

819

820

821

822

828 }

829

830

831

832

833

834

835

836 if (I.hasNoSignedZeros() &&

840 if (I.hasNoSignedZeros() &&

844

845

846

847 if (I.hasNoNaNs() && I.hasNoSignedZeros() && Op0 == Op1 && Op0->hasNUses(2)) {

848

849

853 }

854

858 }

859 }

860

861

862

869 }

870

872 return FoldedPowi;

873

874 if (I.isOnlyUserOfAnyOperand()) {

875

881 }

882

888 }

889

890

891 if (match(Op0, m_IntrinsicIntrinsic::exp(m_Value(X))) &&

892 match(Op1, m_IntrinsicIntrinsic::exp(m_Value(Y)))) {

896 }

897

898

899 if (match(Op0, m_IntrinsicIntrinsic::exp2(m_Value(X))) &&

900 match(Op1, m_IntrinsicIntrinsic::exp2(m_Value(Y)))) {

904 }

905 }

906

907

908

909

910

911

912

913

917 }

921 }

922

923 return nullptr;

924}

925

928 I.getFastMathFlags(),

931

933 return &I;

934

936 return X;

937

939 return Phi;

940

942 return FoldedMul;

943

946

948 return R;

949

950 if (Instruction *R = foldFBinOpOfIntCasts(I))

951 return R;

952

953

954 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

957

958

959

960

963 ((I.hasNoInfs() &&

969 {I.getType()}, {Op1, Op0}, &I);

971 }

972

973

979

980 if (I.hasNoNaNs() && I.hasNoSignedZeros()) {

981

982

983

985 X->getType()->isIntOrIntVectorTy(1)) {

987 SI->copyFastMathFlags(I.getFastMathFlags());

988 return SI;

989 }

991 X->getType()->isIntOrIntVectorTy(1)) {

993 SI->copyFastMathFlags(I.getFastMathFlags());

994 return SI;

995 }

996 }

997

998

1001

1002 if (I.hasAllowReassoc())

1004 return FoldedMul;

1005

1006

1007 if (I.isFast()) {

1009 if (match(Op0, m_OneUse(m_IntrinsicIntrinsic::log2(

1011 Log2 = cast(Op0);

1012 Y = Op1;

1013 }

1014 if (match(Op1, m_OneUse(m_IntrinsicIntrinsic::log2(

1016 Log2 = cast(Op1);

1017 Y = Op0;

1018 }

1023 }

1024 }

1025

1026

1027

1028

1030 Value *Start = nullptr, *Step = nullptr;

1032 I.hasNoSignedZeros() && match(Start, m_Zero()))

1034

1035

1038 m_c_IntrinsicIntrinsic::minimum(m_Deferred(X),

1041

1042

1043

1044 if (!Result->hasNoNaNs())

1045 Result->setHasNoInfs(false);

1046 return Result;

1047 }

1048

1049 return nullptr;

1050}

1051

1052

1053

1054

1056 SelectInst *SI = dyn_cast(I.getOperand(1));

1057 if (!SI)

1058 return false;

1059

1060 int NonNullOperand;

1061 if (match(SI->getTrueValue(), m_Zero()))

1062

1063 NonNullOperand = 2;

1064 else if (match(SI->getFalseValue(), m_Zero()))

1065

1066 NonNullOperand = 1;

1067 else

1068 return false;

1069

1070

1072

1073

1074

1075

1076

1077

1078

1079

1080

1081 Value *SelectCond = SI->getCondition();

1082 if (SI->use_empty() && SelectCond->hasOneUse())

1083 return true;

1084

1085

1088 while (BBI != BBFront) {

1089 --BBI;

1090

1091

1093 break;

1094

1095

1096 for (Use &Op : BBI->operands()) {

1097 if (Op == SI) {

1098 replaceUse(Op, SI->getOperand(NonNullOperand));

1100 } else if (Op == SelectCond) {

1104 }

1105 }

1106

1107

1108 if (&*BBI == SI)

1109 SI = nullptr;

1110 if (&*BBI == SelectCond)

1111 SelectCond = nullptr;

1112

1113

1114 if (!SelectCond && !SI)

1115 break;

1116

1117 }

1118 return true;

1119}

1120

1121

1123 bool IsSigned) {

1124 bool Overflow;

1125 Product = IsSigned ? C1.smul_ov(C2, Overflow) : C1.umul_ov(C2, Overflow);

1126 return Overflow;

1127}

1128

1129

1131 bool IsSigned) {

1133

1134

1136 return false;

1137

1138

1140 return false;

1141

1143 if (IsSigned)

1145 else

1147

1149}

1150

1152 assert((I.getOpcode() == Instruction::SDiv ||

1153 I.getOpcode() == Instruction::UDiv) &&

1154 "Expected integer divide");

1155

1156 bool IsSigned = I.getOpcode() == Instruction::SDiv;

1157 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

1158 Type *Ty = I.getType();

1159

1161

1162

1163

1166

1167 auto *Mul = cast(Op0);

1168 auto *Shl = cast(Op1);

1169 bool HasNUW = Mul->hasNoUnsignedWrap() && Shl->hasNoUnsignedWrap();

1170 bool HasNSW = Mul->hasNoSignedWrap() && Shl->hasNoSignedWrap();

1171

1172

1173 if (!IsSigned && HasNUW)

1174 return Builder.CreateLShr(Y, Z, "", I.isExact());

1175

1176

1177 if (IsSigned && HasNSW && (Op0->hasOneUse() || Op1->hasOneUse())) {

1178 Value *Shl = Builder.CreateShl(ConstantInt::get(Ty, 1), Z);

1179 return Builder.CreateSDiv(Y, Shl, "", I.isExact());

1180 }

1181 }

1182

1183

1184

1187 auto *Shl0 = cast(Op0);

1188 auto *Shl1 = cast(Op1);

1189

1190

1191

1192

1193 if (!IsSigned &&

1194 ((Shl0->hasNoUnsignedWrap() && Shl1->hasNoUnsignedWrap()) ||

1195 (Shl0->hasNoUnsignedWrap() && Shl0->hasNoSignedWrap() &&

1196 Shl1->hasNoSignedWrap())))

1197 return Builder.CreateUDiv(X, Y, "", I.isExact());

1198

1199

1200

1201 if (IsSigned && Shl0->hasNoSignedWrap() && Shl1->hasNoSignedWrap() &&

1202 Shl1->hasNoUnsignedWrap())

1203 return Builder.CreateSDiv(X, Y, "", I.isExact());

1204 }

1205

1206

1207

1210 auto *Shl0 = cast(Op0);

1211 auto *Shl1 = cast(Op1);

1212

1213 if (IsSigned ? (Shl0->hasNoSignedWrap() && Shl1->hasNoSignedWrap())

1214 : (Shl0->hasNoUnsignedWrap() && Shl1->hasNoUnsignedWrap())) {

1215 Constant *One = ConstantInt::get(X->getType(), 1);

1216

1217

1219 One, Y, "shl.dividend",

1220 true,

1221

1222 IsSigned ? (Shl0->hasNoUnsignedWrap() || Shl1->hasNoUnsignedWrap())

1223 : Shl0->hasNoSignedWrap());

1224 return Builder.CreateLShr(Dividend, Z, "", I.isExact());

1225 }

1226 }

1227

1228 return nullptr;

1229}

1230

1231

1233 assert(I.isIntDivRem() && "Unexpected instruction");

1234 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

1235

1236

1237

1238 auto *Op1C = dyn_cast(Op1);

1239 Type *Ty = I.getType();

1240 auto *VTy = dyn_cast(Ty);

1241 if (Op1C && VTy) {

1242 unsigned NumElts = VTy->getNumElements();

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

1245 if (Elt && (Elt->isNullValue() || isa(Elt)))

1247 }

1248 }

1249

1251 return Phi;

1252

1253

1256

1257

1259 return &I;

1260

1261

1262

1263

1264

1268 true))

1269 return R;

1270 }

1271

1272 return nullptr;

1273}

1274

1275

1276

1277

1278

1281 return Res;

1282

1283 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

1284 bool IsSigned = I.getOpcode() == Instruction::SDiv;

1285 Type *Ty = I.getType();

1286

1287 const APInt *C2;

1290 const APInt *C1;

1291

1292

1298 ConstantInt::get(Ty, Product));

1299 }

1300

1304

1305

1306 if (isMultiple(*C2, *C1, Quotient, IsSigned)) {

1308 ConstantInt::get(Ty, Quotient));

1309 NewDiv->setIsExact(I.isExact());

1310 return NewDiv;

1311 }

1312

1313

1314 if (isMultiple(*C1, *C2, Quotient, IsSigned)) {

1316 ConstantInt::get(Ty, Quotient));

1317 auto *OBO = cast(Op0);

1318 Mul->setHasNoUnsignedWrap(!IsSigned && OBO->hasNoUnsignedWrap());

1319 Mul->setHasNoSignedWrap(OBO->hasNoSignedWrap());

1320 return Mul;

1321 }

1322 }

1323

1330

1331

1332 if (isMultiple(*C2, C1Shifted, Quotient, IsSigned)) {

1334 ConstantInt::get(Ty, Quotient));

1335 BO->setIsExact(I.isExact());

1336 return BO;

1337 }

1338

1339

1340 if (isMultiple(C1Shifted, *C2, Quotient, IsSigned)) {

1342 ConstantInt::get(Ty, Quotient));

1343 auto *OBO = cast(Op0);

1344 Mul->setHasNoUnsignedWrap(!IsSigned && OBO->hasNoUnsignedWrap());

1345 Mul->setHasNoSignedWrap(OBO->hasNoSignedWrap());

1346 return Mul;

1347 }

1348 }

1349

1350

1351

1352

1353

1354 if (IsSigned &&

1357 isMultiple(*C1, *C2, Quotient, IsSigned)) {

1358 return BinaryOperator::CreateNSWAdd(X, ConstantInt::get(Ty, Quotient));

1359 }

1360 if (!IsSigned &&

1363 return BinaryOperator::CreateNUWAdd(X,

1364 ConstantInt::get(Ty, C1->udiv(*C2)));

1365 }

1366

1367 if (!C2->isZero())

1369 return FoldedDiv;

1370 }

1371

1374 if (IsSigned) {

1375

1376

1377

1378 Value *F1 = Op1;

1384 } else {

1385

1386

1388 }

1389 }

1390

1391

1393 return &I;

1394

1395

1401

1402

1405 return BinaryOperator::CreateNSWShl(ConstantInt::get(Ty, 1), Y);

1407 return BinaryOperator::CreateNUWShl(ConstantInt::get(Ty, 1), Y);

1408

1409

1411 bool HasNSW = cast(Op1)->hasNoSignedWrap();

1412 bool HasNUW = cast(Op1)->hasNoUnsignedWrap();

1413 if ((IsSigned && HasNSW) || (!IsSigned && HasNUW)) {

1416 return &I;

1417 }

1418 }

1419

1420

1421

1422 if (!IsSigned && Op1->hasOneUse() &&

1425 if (cast(Op1)->hasNoUnsignedWrap()) {

1426 Instruction *NewDiv = BinaryOperator::CreateUDiv(

1427 Builder.CreateShl(ConstantInt::get(Ty, 1), Z, "", true), Y);

1429 return NewDiv;

1430 }

1431

1434

1435

1436

1437

1440 auto *InnerDiv = cast(Op0);

1441 auto *Mul = cast(InnerDiv->getOperand(0));

1443 if (!IsSigned && Mul->hasNoUnsignedWrap())

1444 NewDiv = BinaryOperator::CreateUDiv(X, Y);

1445 else if (IsSigned && Mul->hasNoSignedWrap())

1446 NewDiv = BinaryOperator::CreateSDiv(X, Y);

1447

1448

1449 if (NewDiv) {

1450 NewDiv->setIsExact(I.isExact() && InnerDiv->isExact());

1451 return NewDiv;

1452 }

1453 }

1454

1455

1457 auto OB0HasNSW = cast(Op0)->hasNoSignedWrap();

1458 auto OB0HasNUW = cast(Op0)->hasNoUnsignedWrap();

1459

1461 auto OB1HasNSW = cast(Op1)->hasNoSignedWrap();

1462 auto OB1HasNUW =

1463 cast(Op1)->hasNoUnsignedWrap();

1464 const APInt *C1, *C2;

1465 if (IsSigned && OB0HasNSW) {

1467 return BinaryOperator::CreateSDiv(A, B);

1468 }

1469 if (!IsSigned && OB0HasNUW) {

1470 if (OB1HasNUW)

1471 return BinaryOperator::CreateUDiv(A, B);

1473 return BinaryOperator::CreateUDiv(A, B);

1474 }

1475 return nullptr;

1476 };

1477

1479 if (auto *Val = CreateDivOrNull(Y, Z))

1480 return Val;

1481 }

1483 if (auto *Val = CreateDivOrNull(X, Z))

1484 return Val;

1485 }

1486 }

1487 return nullptr;

1488}

1489

1491 bool DoFold) {

1493 if (!DoFold)

1494 return reinterpret_cast<Value *>(-1);

1495 return Fn();

1496 };

1497

1498

1499

1500

1502 return IfFold([&]() {

1504 if (C)

1505 llvm_unreachable("Failed to constant fold udiv -> logbase2");

1506 return C;

1507 });

1508

1509

1511 return nullptr;

1512

1513

1514

1518 return IfFold([&]() { return Builder.CreateZExt(LogX, Op->getType()); });

1519

1520

1521

1523 auto *TI = cast(Op);

1524 if (AssumeNonZero || TI->hasNoUnsignedWrap())

1526 return IfFold([&]() {

1528 TI->hasNoUnsignedWrap());

1529 });

1530 }

1531

1532

1533

1535 auto *BO = cast(Op);

1536

1537 if (AssumeNonZero || BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap())

1540 }

1541

1542

1543

1545 auto *PEO = cast(Op);

1546 if (AssumeNonZero || PEO->isExact())

1549 }

1550

1551

1552

1555 return IfFold([&]() { return LogX; });

1557 return IfFold([&]() { return LogY; });

1558 }

1559

1560

1561

1562 if (SelectInst *SI = dyn_cast(Op))

1563 if (Value *LogX = takeLog2(SI->getOperand(1), Depth, AssumeNonZero, DoFold))

1564 if (Value *LogY =

1565 takeLog2(SI->getOperand(2), Depth, AssumeNonZero, DoFold))

1566 return IfFold([&]() {

1568 });

1569

1570

1571

1572 auto *MinMax = dyn_cast(Op);

1574

1575

1577 false, DoFold))

1579 false, DoFold))

1580 return IfFold([&]() {

1582 LogY);

1583 });

1584 }

1585

1586 return nullptr;

1587}

1588

1589

1590

1594 Value *N = I.getOperand(0);

1595 Value *D = I.getOperand(1);

1596 Type *Ty = I.getType();

1599 X->getType() == Y->getType() && (N->hasOneUse() || D->hasOneUse())) {

1600

1601

1603 return new ZExtInst(NarrowOp, Ty);

1604 }

1605

1609

1611 if (!TruncC)

1612 return nullptr;

1613

1614

1615

1617 }

1620

1622 if (!TruncC)

1623 return nullptr;

1624

1625

1626

1628 }

1629

1630 return nullptr;

1631}

1632

1637

1639 return X;

1640

1641

1643 return Common;

1644

1645 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

1647 const APInt *C1, *C2;

1649

1650 bool Overflow;

1652 if (!Overflow) {

1655 X, ConstantInt::get(X->getType(), C2ShlC1));

1656 if (IsExact)

1658 return BO;

1659 }

1660 }

1661

1662

1663

1664 Type *Ty = I.getType();

1668 }

1669

1670 if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {

1673 }

1674

1676 return NarrowDiv;

1677

1679

1680

1681

1684 Instruction *Lshr = BinaryOperator::CreateLShr(A, B);

1685 if (I.isExact() && cast(Op0)->isExact())

1687 return Lshr;

1688 }

1689

1690 auto GetShiftableDenom = [&](Value *Denom) -> Value * {

1691

1693 return Log2;

1694

1695

1697

1698

1699

1702

1703 return nullptr;

1704 };

1705

1706 if (auto *Res = GetShiftableDenom(Op1))

1709

1710 return nullptr;

1711}

1712

1717

1719 return X;

1720

1721

1723 return Common;

1724

1725 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

1726 Type *Ty = I.getType();

1728

1729

1733

1734

1737

1738 if (I.isExact()) {

1739

1742 return BinaryOperator::CreateExactAShr(Op0, C);

1743 }

1744

1745

1748 return BinaryOperator::CreateExactAShr(Op0, ShAmt);

1749

1750

1756 }

1757 }

1758

1759 const APInt *Op1C;

1761

1762

1763

1768

1769

1770

1771

1772

1776 return new SExtInst(NarrowOp, Ty);

1777 }

1778

1779

1780

1781

1783 Constant *NegC = ConstantInt::get(Ty, -(*Op1C));

1784 Instruction *BO = BinaryOperator::CreateSDiv(X, NegC);

1786 return BO;

1787 }

1788 }

1789

1790

1795

1796

1797

1804 }

1805

1807 if (I.isExact() &&

1810 I.setIsExact();

1811 return &I;

1812 }

1813

1815

1817 auto *BO = BinaryOperator::CreateUDiv(Op0, Op1, I.getName());

1818 BO->setIsExact(I.isExact());

1819 return BO;

1820 }

1821

1823

1824

1829 }

1830

1832

1833

1834

1835

1836 auto *BO = BinaryOperator::CreateUDiv(Op0, Op1, I.getName());

1837 BO->setIsExact(I.isExact());

1838 return BO;

1839 }

1840 }

1841

1842

1848 }

1849 return nullptr;

1850}

1851

1852

1856 return nullptr;

1857

1858

1864

1865

1866

1867 if (I.hasNoNaNs() &&

1871 CallInst *CopySign = B.CreateIntrinsic(

1872 Intrinsic::copysign, {C->getType()},

1876 }

1877

1878

1879

1880

1881 if (!(C->hasExactInverseFP() || (I.hasAllowReciprocal() && C->isNormalFP())))

1882 return nullptr;

1883

1884

1885

1886

1887

1889 Instruction::FDiv, ConstantFP::get(I.getType(), 1.0), C, DL);

1890 if (!RecipC || !RecipC->isNormalFP())

1891 return nullptr;

1892

1893

1895}

1896

1897

1901 return nullptr;

1902

1903

1909

1910 if (I.hasAllowReassoc() || I.hasAllowReciprocal())

1911 return nullptr;

1912

1913

1914 Constant *C2, *NewC = nullptr;

1916

1919

1921 }

1922

1923

1924

1925

1927 return nullptr;

1928

1930}

1931

1932

1935 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

1936 auto *II = dyn_cast(Op1);

1937 if (II || II->hasOneUse() || I.hasAllowReassoc() ||

1938 I.hasAllowReciprocal())

1939 return nullptr;

1940

1941

1942

1943

1944

1947 switch (IID) {

1948 case Intrinsic::pow:

1949 Args.push_back(II->getArgOperand(0));

1950 Args.push_back(Builder.CreateFNegFMF(II->getArgOperand(1), &I));

1951 break;

1952 case Intrinsic::powi: {

1953

1954

1955

1956

1957

1958 if (I.hasNoInfs())

1959 return nullptr;

1960 Args.push_back(II->getArgOperand(0));

1961 Args.push_back(Builder.CreateNeg(II->getArgOperand(1)));

1962 Type *Tys[] = {I.getType(), II->getArgOperand(1)->getType()};

1965 }

1966 case Intrinsic::exp:

1967 case Intrinsic::exp2:

1968 Args.push_back(Builder.CreateFNegFMF(II->getArgOperand(0), &I));

1969 break;

1970 default:

1971 return nullptr;

1972 }

1975}

1976

1977

1978

1981

1982 if (I.hasAllowReassoc() || I.hasAllowReciprocal())

1983 return nullptr;

1984 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

1985 auto *II = dyn_cast(Op1);

1986 if (II || II->getIntrinsicID() != Intrinsic::sqrt || II->hasOneUse() ||

1987 II->hasAllowReassoc() || II->hasAllowReciprocal())

1988 return nullptr;

1989

1991 auto *DivOp = dyn_cast(II->getOperand(0));

1992 if (!DivOp)

1993 return nullptr;

1995 return nullptr;

1996 if (!DivOp->hasAllowReassoc() || I.hasAllowReciprocal() ||

1997 !DivOp->hasOneUse())

1998 return nullptr;

2000 Value *NewSqrt =

2003}

2004

2005

2006

2007

2008

2009

2010

2011

2012

2013

2014

2015

2016

2017

2023

2024 B.SetInsertPoint(X);

2025

2026

2027

2029 auto *FDiv = cast(

2030 B.CreateFDiv(ConstantFP::get(X->getType(), 1.0), SqrtOp));

2031 auto *R1FPMathMDNode = (*R1.begin())->getMetadata(LLVMContext::MD_fpmath);

2032 FastMathFlags R1FMF = (*R1.begin())->getFastMathFlags();

2035 R1FPMathMDNode, I->getMetadata(LLVMContext::MD_fpmath));

2036 R1FMF &= I->getFastMathFlags();

2039 }

2040 FDiv->setMetadata(LLVMContext::MD_fpmath, R1FPMathMDNode);

2041 FDiv->copyFastMathFlags(R1FMF);

2042

2043

2044

2045

2046 auto *FSqrt = cast(CI->clone());

2047 FSqrt->insertBefore(CI);

2048 auto *R2FPMathMDNode = (*R2.begin())->getMetadata(LLVMContext::MD_fpmath);

2049 FastMathFlags R2FMF = (*R2.begin())->getFastMathFlags();

2052 R2FPMathMDNode, I->getMetadata(LLVMContext::MD_fpmath));

2053 R2FMF &= I->getFastMathFlags();

2056 }

2057 FSqrt->setMetadata(LLVMContext::MD_fpmath, R2FPMathMDNode);

2058 FSqrt->copyFastMathFlags(R2FMF);

2059

2061

2063 Value *Mul = B.CreateFMul(FDiv, FSqrt);

2064 FMul = cast(B.CreateFNeg(Mul));

2065 } else

2066 FMul = cast(B.CreateFMul(FDiv, FSqrt));

2067 FMul->copyMetadata(*X);

2071}

2072

2074 Module *M = I.getModule();

2075

2077 I.getFastMathFlags(),

2080

2082 return X;

2083

2085 return Phi;

2086

2087 if (Instruction *R = foldFDivConstantDivisor(I))

2088 return R;

2089

2091 return R;

2092

2094 return R;

2095

2096 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

2097

2098

2099

2100

2101

2102

2103

2104

2105

2106

2107

2110 CallInst *CI = cast(I.getOperand(1));

2112 return D;

2113 }

2114

2115 if (isa(Op0))

2116 if (SelectInst *SI = dyn_cast(Op1))

2118 return R;

2119

2120 if (isa(Op1))

2121 if (SelectInst *SI = dyn_cast(Op0))

2123 return R;

2124

2125 if (I.hasAllowReassoc() && I.hasAllowReciprocal()) {

2128 (!isa(Y) || !isa(Op1))) {

2129

2132 }

2134 (!isa(Y) || !isa(Op0))) {

2135

2138 }

2139

2140

2141

2142

2143

2144

2147 }

2148

2149 if (I.hasAllowReassoc() && Op0->hasOneUse() && Op1->hasOneUse()) {

2150

2151

2153 bool IsTan = match(Op0, m_IntrinsicIntrinsic::sin(m_Value(X))) &&

2155 bool IsCot =

2156 !IsTan && match(Op0, m_IntrinsicIntrinsic::cos(m_Value(X))) &&

2158

2159 if ((IsTan || IsCot) && hasFloatFn(M, &TLI, I.getType(), LibFunc_tan,

2160 LibFunc_tanf, LibFunc_tanl)) {

2163 B.setFastMathFlags(I.getFastMathFlags());

2165 cast(Op0)->getCalledFunction()->getAttributes();

2167 LibFunc_tanl, B, Attrs);

2168 if (IsCot)

2169 Res = B.CreateFDiv(ConstantFP::get(I.getType(), 1.0), Res);

2171 }

2172 }

2173

2174

2175

2176

2178 if (I.hasNoNaNs() && I.hasAllowReassoc() &&

2182 return &I;

2183 }

2184

2185

2186

2187 if (I.hasNoNaNs() && I.hasNoInfs() &&

2191 Intrinsic::copysign, ConstantFP::get(I.getType(), 1.0), X, &I);

2193 }

2194

2196 return Mul;

2197

2199 return Mul;

2200

2201

2202 if (I.hasAllowReassoc() &&

2209 }

2210

2212 return FoldedPowi;

2213

2214 return nullptr;

2215}

2216

2217

2218

2219

2220

2221

2222

2225 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *X = nullptr;

2227 bool ShiftByX = false;

2228

2229

2231 bool &PreserveNSW) -> bool {

2232 const APInt *Tmp = nullptr;

2235 C = *Tmp;

2239

2241 }

2242 if (Tmp != nullptr)

2243 return true;

2244

2245

2246 V = nullptr;

2247 return false;

2248 };

2249

2251 const APInt *Tmp = nullptr;

2254 C = *Tmp;

2255 return true;

2256 }

2257

2258

2259 V = nullptr;

2260 return false;

2261 };

2262

2263 bool Op0PreserveNSW = true, Op1PreserveNSW = true;

2264 if (MatchShiftOrMulXC(Op0, X, Y, Op0PreserveNSW) &&

2265 MatchShiftOrMulXC(Op1, X, Z, Op1PreserveNSW)) {

2266

2267 } else if (MatchShiftCX(Op0, Y, X) && MatchShiftCX(Op1, Z, X)) {

2268 ShiftByX = true;

2269 } else {

2270 return nullptr;

2271 }

2272

2273 bool IsSRem = I.getOpcode() == Instruction::SRem;

2274

2276

2277

2278 bool BO0HasNSW = Op0PreserveNSW && BO0->hasNoSignedWrap();

2280 bool BO0NoWrap = IsSRem ? BO0HasNSW : BO0HasNUW;

2281

2282 APInt RemYZ = IsSRem ? Y.srem(Z) : Y.urem(Z);

2283

2284

2285

2286 if (RemYZ.isZero() && BO0NoWrap)

2288

2289

2290

2291

2292 auto CreateMulOrShift =

2294 Value *RemSimplification =

2295 ConstantInt::get(I.getType(), RemSimplificationC);

2296 return ShiftByX ? BinaryOperator::CreateShl(RemSimplification, X)

2297 : BinaryOperator::CreateMul(X, RemSimplification);

2298 };

2299

2301 bool BO1HasNSW = Op1PreserveNSW && BO1->hasNoSignedWrap();

2303 bool BO1NoWrap = IsSRem ? BO1HasNSW : BO1HasNUW;

2304

2305

2306

2307 if (RemYZ == Y && BO1NoWrap) {

2309

2312 return BO;

2313 }

2314

2315

2316

2317

2318 if (Y.uge(Z) && (IsSRem ? (BO0HasNSW && BO1HasNSW) : BO0HasNUW)) {

2322 return BO;

2323 }

2324

2325 return nullptr;

2326}

2327

2328

2329

2330

2331

2334 return Res;

2335

2336 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

2337

2338 if (isa(Op1)) {

2339 if (Instruction *Op0I = dyn_cast(Op0)) {

2340 if (SelectInst *SI = dyn_cast(Op0I)) {

2342 return R;

2343 } else if (auto *PN = dyn_cast(Op0I)) {

2344 const APInt *Op1Int;

2346 (I.getOpcode() == Instruction::URem ||

2348

2349

2350

2352 return NV;

2353 }

2354 }

2355

2356

2358 return &I;

2359 }

2360 }

2361

2363 return R;

2364

2365 return nullptr;

2366}

2367

2372

2374 return X;

2375

2377 return common;

2378

2380 return NarrowRem;

2381

2382

2383 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

2384 Type *Ty = I.getType();

2386

2387

2390 return BinaryOperator::CreateAnd(Op0, Add);

2391 }

2392

2393

2397 }

2398

2399

2400

2402 Value *F0 = Op0;

2408 }

2409

2410

2411

2412

2413

2415 if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {

2416 Value *FrozenOp0 = Op0;

2422 }

2423

2424

2429 Value *FrozenOp0 = Op0;

2434 }

2435 }

2436

2437 return nullptr;

2438}

2439

2444

2446 return X;

2447

2448

2450 return Common;

2451

2452 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

2453 {

2455

2457 return replaceOperand(I, 1, ConstantInt::get(I.getType(), -*Y));

2458 }

2459

2460

2464

2465

2466

2470

2471 return BinaryOperator::CreateURem(Op0, Op1, I.getName());

2472 }

2473

2474

2475 if (isa(Op1) || isa(Op1)) {

2476 Constant *C = cast(Op1);

2477 unsigned VWidth = cast(C->getType())->getNumElements();

2478

2479 bool hasNegative = false;

2480 bool hasMissing = false;

2481 for (unsigned i = 0; i != VWidth; ++i) {

2482 Constant *Elt = C->getAggregateElement(i);

2483 if (!Elt) {

2484 hasMissing = true;

2485 break;

2486 }

2487

2489 if (RHS->isNegative())

2490 hasNegative = true;

2491 }

2492

2493 if (hasNegative && !hasMissing) {

2495 for (unsigned i = 0; i != VWidth; ++i) {

2496 Elts[i] = C->getAggregateElement(i);

2497 if (ConstantInt *RHS = dyn_cast(Elts[i])) {

2498 if (RHS->isNegative())

2500 }

2501 }

2502

2504 if (NewRHSV != C)

2506 }

2507 }

2508

2509 return nullptr;

2510}

2511

2514 I.getFastMathFlags(),

2517

2519 return X;

2520

2522 return Phi;

2523

2524 return nullptr;

2525}

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static const Function * getParent(const Value *V)

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

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

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

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

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

This file provides internal interfaces used to implement the InstCombine.

static Instruction * convertFSqrtDivIntoFMul(CallInst *CI, Instruction *X, const SmallPtrSetImpl< Instruction * > &R1, const SmallPtrSetImpl< Instruction * > &R2, InstCombiner::BuilderTy &B, InstCombinerImpl *IC)

static Instruction * simplifyIRemMulShl(BinaryOperator &I, InstCombinerImpl &IC)

static Instruction * narrowUDivURem(BinaryOperator &I, InstCombinerImpl &IC)

If we have zero-extended operands of an unsigned div or rem, we may be able to narrow the operation (...

static Value * simplifyValueKnownNonZero(Value *V, InstCombinerImpl &IC, Instruction &CxtI)

The specific integer value is used in a context where it is known to be non-zero.

static bool getFSqrtDivOptPattern(Instruction *Div, SmallPtrSetImpl< Instruction * > &R1, SmallPtrSetImpl< Instruction * > &R2)

static Value * foldMulSelectToNegate(BinaryOperator &I, InstCombiner::BuilderTy &Builder)

static bool isFSqrtDivToFMulLegal(Instruction *X, SmallPtrSetImpl< Instruction * > &R1, SmallPtrSetImpl< Instruction * > &R2)

static Instruction * foldFDivPowDivisor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)

Negate the exponent of pow/exp to fold division-by-pow() into multiply.

static bool multiplyOverflows(const APInt &C1, const APInt &C2, APInt &Product, bool IsSigned)

True if the multiply can not be expressed in an int this size.

static Value * foldMulShl1(BinaryOperator &Mul, bool CommuteOperands, InstCombiner::BuilderTy &Builder)

Reduce integer multiplication patterns that contain a (+/-1 << Z) factor.

static bool isMultiple(const APInt &C1, const APInt &C2, APInt &Quotient, bool IsSigned)

True if C1 is a multiple of C2. Quotient contains C1/C2.

static Instruction * foldFDivSqrtDivisor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)

Convert div to mul if we have an sqrt divisor iff sqrt's operand is a fdiv instruction.

static Instruction * foldFDivConstantDividend(BinaryOperator &I)

Remove negation and try to reassociate constant math.

static Value * foldIDivShl(BinaryOperator &I, InstCombiner::BuilderTy &Builder)

This file provides the interface for the instcombine pass implementation.

static bool hasNoSignedWrap(BinaryOperator &I)

static bool hasNoUnsignedWrap(BinaryOperator &I)

uint64_t IntrinsicInst * II

static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")

const SmallVectorImpl< MachineOperand > & Cond

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallPtrSet class.

This file defines the SmallVector class.

Class for arbitrary precision integers.

APInt umul_ov(const APInt &RHS, bool &Overflow) const

APInt udiv(const APInt &RHS) const

Unsigned division operation.

static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)

Dual division/remainder interface.

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.

static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)

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.

bool ult(const APInt &RHS) const

Unsigned less than comparison.

bool isMinValue() const

Determine if this is the smallest unsigned value.

unsigned countr_zero() const

Count the number of trailing zero bits.

static APInt getSignedMinValue(unsigned numBits)

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

APInt ushl_ov(const APInt &Amt, bool &Overflow) const

unsigned getSignificantBits() const

Get the minimum bit size for this signed APInt.

APInt smul_ov(const APInt &RHS, bool &Overflow) const

bool ule(const APInt &RHS) const

Unsigned less or equal comparison.

static APInt getOneBitSet(unsigned numBits, unsigned BitNo)

Return an APInt with exactly one bit set in the result.

LLVM Basic Block Representation.

InstListType::iterator iterator

Instruction iterators...

static BinaryOperator * CreateFAddFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")

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

Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...

BinaryOps getOpcode() const

static BinaryOperator * CreateExact(BinaryOps Opc, Value *V1, Value *V2, const Twine &Name="")

static 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.

static BinaryOperator * CreateFMulFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")

static BinaryOperator * CreateFDivFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")

static BinaryOperator * CreateFSubFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")

static BinaryOperator * CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, Value *CopyO, const Twine &Name="", InsertPosition InsertBefore=nullptr)

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

Value * getArgOperand(unsigned i) const

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

static CastInst * CreateZExtOrBitCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Create a ZExt or BitCast cast instruction.

static 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 ...

static Type * makeCmpResultType(Type *opnd_type)

Create a result type for fcmp/icmp.

@ ICMP_ULT

unsigned less than

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

static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)

static Constant * getExactLogBase2(Constant *C)

If C is a scalar/fixed width vector of known powers of 2, then this function returns a new scalar/fix...

static Constant * getInfinity(Type *Ty, bool Negative=false)

This is the shared class of boolean and integer constants.

static ConstantInt * getTrue(LLVMContext &Context)

static ConstantInt * getFalse(LLVMContext &Context)

static ConstantInt * getBool(LLVMContext &Context, bool V)

static Constant * get(ArrayRef< Constant * > V)

This is an important base class in LLVM.

static Constant * getAllOnesValue(Type *Ty)

bool isNormalFP() const

Return true if this is a normal (as opposed to denormal, infinity, nan, or zero) floating-point scala...

static Constant * getNullValue(Type *Ty)

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

Constant * getAggregateElement(unsigned Elt) const

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

bool isNotMinSignedValue() const

Return true if the value is not the smallest signed value, or, for vectors, does not contain smallest...

bool isNullValue() const

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

This class represents an Operation in the Expression.

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

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

static FastMathFlags intersectRewrite(FastMathFlags LHS, FastMathFlags RHS)

Intersect rewrite-based flags.

static FastMathFlags unionValue(FastMathFlags LHS, FastMathFlags RHS)

Union value flags.

bool allowReassoc() const

Flag queries.

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

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

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

ConstantInt * getTrue()

Get the constant value for i1 true.

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

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

Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)

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

Return a boolean value testing if Arg > -1.

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

Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)

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

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

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.

CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")

Create a call to intrinsic ID with Args, mangled using Types.

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

Value * CreateBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)

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

Return a boolean value testing if Arg < 0.

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

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 * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)

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)

Value * CreateSDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)

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

Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)

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

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

Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)

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

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

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

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

Instruction * visitMul(BinaryOperator &I)

Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false)

Given an instruction with a select as one operand and a constant as the other operand,...

Instruction * foldBinOpOfSelectAndCastOfSelectCondition(BinaryOperator &I)

Tries to simplify binops of select and cast of the select condition.

Instruction * foldBinOpIntoSelectOrPhi(BinaryOperator &I)

This is a convenience wrapper function for the above two functions.

Instruction * visitUDiv(BinaryOperator &I)

bool SimplifyAssociativeOrCommutative(BinaryOperator &I)

Performs a few simplifications for operators which are associative or commutative.

Value * foldUsingDistributiveLaws(BinaryOperator &I)

Tries to simplify binary operations which some other binary operation distributes over.

Instruction * visitURem(BinaryOperator &I)

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,...

Value * takeLog2(Value *Op, unsigned Depth, bool AssumeNonZero, bool DoFold)

Take the exact integer log2 of the value.

Instruction * visitSRem(BinaryOperator &I)

Instruction * visitFDiv(BinaryOperator &I)

bool simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I)

Fold a divide or remainder with a select instruction divisor when one of the select operands is zero.

Constant * getLosslessUnsignedTrunc(Constant *C, Type *TruncTy)

Instruction * eraseInstFromFunction(Instruction &I) override

Combiner aware instruction erasure.

Instruction * commonIDivRemTransforms(BinaryOperator &I)

Common integer divide/remainder transforms.

Value * tryGetLog2(Value *Op, bool AssumeNonZero)

Instruction * commonIDivTransforms(BinaryOperator &I)

This function implements the transforms common to both integer division instructions (udiv and sdiv).

Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)

For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.

Instruction * visitFRem(BinaryOperator &I)

bool SimplifyDemandedInstructionBits(Instruction &Inst)

Tries to simplify operands to an integer instruction based on its demanded bits.

Instruction * visitFMul(BinaryOperator &I)

Instruction * foldFMulReassoc(BinaryOperator &I)

Instruction * foldVectorBinop(BinaryOperator &Inst)

Canonicalize the position of binops relative to shufflevector.

Value * SimplifySelectsFeedingBinaryOp(BinaryOperator &I, Value *LHS, Value *RHS)

Instruction * foldPowiReassoc(BinaryOperator &I)

Instruction * visitSDiv(BinaryOperator &I)

Instruction * commonIRemTransforms(BinaryOperator &I)

This function implements the transforms common to both integer remainder instructions (urem and srem)...

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

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

A combiner-aware RAUW-like routine.

void replaceUse(Use &U, Value *NewValue)

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

InstructionWorklist & Worklist

A worklist of the instructions that need to be simplified.

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

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

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

bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth=0, const Instruction *CxtI=nullptr) const

void push(Instruction *I)

Push the instruction onto the worklist stack.

Instruction * clone() const

Create a copy of 'this' instruction that is identical in all ways except the following:

void setHasNoUnsignedWrap(bool b=true)

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

bool hasNoNaNs() const LLVM_READONLY

Determine whether the no-NaNs flag is set.

bool hasNoUnsignedWrap() const LLVM_READONLY

Determine whether the no unsigned wrap flag is set.

bool hasNoInfs() const LLVM_READONLY

Determine whether the no-infs flag is set.

bool hasNoSignedZeros() const LLVM_READONLY

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

bool hasNoSignedWrap() const LLVM_READONLY

Determine whether the no signed wrap flag is set.

void setHasNoSignedWrap(bool b=true)

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

bool isExact() const LLVM_READONLY

Determine whether the exact flag is set.

void setMetadata(unsigned KindID, MDNode *Node)

Set the metadata of the specified kind to the specified node.

FastMathFlags getFastMathFlags() const LLVM_READONLY

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

void setIsExact(bool b=true)

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

bool hasAllowReassoc() const LLVM_READONLY

Determine whether the allow-reassociation flag is set.

A wrapper class for inspecting calls to intrinsic functions.

static MDNode * getMostGenericFPMath(MDNode *A, MDNode *B)

A Module instance is used to store all the information related to an LLVM module.

static Value * Negate(bool LHSIsZero, bool IsNSW, Value *Root, InstCombinerImpl &IC)

Attempt to negate Root.

Utility class for integer operators which may exhibit overflow - Add, Sub, Mul, and Shl.

bool hasNoSignedWrap() const

Test whether this operation is known to never undergo signed overflow, aka the nsw property.

bool hasNoUnsignedWrap() const

Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.

static PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

This class represents a sign extension of integer types.

This class represents the LLVM 'select' instruction.

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

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

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

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

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

bool isIntOrIntVectorTy() const

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

unsigned getScalarSizeInBits() const LLVM_READONLY

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

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

A Use represents the edge between a Value definition and its users.

Value * getOperand(unsigned i) const

LLVM Value Representation.

Type * getType() const

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

bool hasOneUse() const

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

iterator_range< user_iterator > users()

bool hasNUses(unsigned N) const

Return true if this Value has exactly N uses.

StringRef getName() const

Return a constant reference to the value's name.

void takeName(Value *V)

Transfer the name from V to this value.

This class represents zero extension of integer types.

An efficient, type-erasing, non-owning reference to a callable.

#define llvm_unreachable(msg)

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

@ C

The default llvm calling convention, compatible with C.

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)

cst_pred_ty< is_negative > m_Negative()

Match an integer or vector of negative values.

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.

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.

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.

BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)

class_match< Constant > m_Constant()

Match an arbitrary Constant and ignore it.

AllowReassoc_match< T > m_AllowReassoc(const T &SubPattern)

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

Matches Trunc.

specific_intval< false > m_SpecificInt(const APInt &V)

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

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

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

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.

specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)

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'.

cst_pred_ty< is_nonnegative > m_NonNegative()

Match an integer or vector of non-negative values.

cst_pred_ty< is_one > m_One()

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

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

Matches SelectInst.

specific_fpval m_SpecificFP(double V)

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

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

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

BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(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()...

apint_match m_APIntAllowPoison(const APInt *&Res)

Match APInt while allowing poison in splat vector constants.

OneUse_match< T > m_OneUse(const T &SubPattern)

BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)

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

match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()

Match an arbitrary immediate Constant and ignore it.

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

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

Matches ZExt.

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

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

BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)

cst_pred_ty< is_negated_power2 > m_NegatedPower2()

Match a integer or vector negated power-of-2.

cst_pred_ty< custom_checkfn< APInt > > m_CheckedInt(function_ref< bool(const APInt &)> CheckFn)

Match an integer or vector where CheckFn(ele) for each element is true.

specific_fpval m_FPOne()

Match a float 1.0 or vector with all elements equal to 1.0.

apfloat_match m_APFloatAllowPoison(const APFloat *&Res)

Match APFloat while allowing poison in splat vector constants.

match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)

Match either "add" or "or disjoint".

CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)

BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)

apint_match m_APInt(const APInt *&Res)

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

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

Match either "add nsw" or "or disjoint".

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.

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

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

Exact_match< T > m_Exact(const T &SubPattern)

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.

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

BinaryOp_match< LHS, RHS, Instruction::FDiv > m_FDiv(const LHS &L, const RHS &R)

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

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

Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.

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.

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

Match either "add nuw" or "or disjoint".

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

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.

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

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

This is an optimization pass for GlobalISel generic memory operations.

Value * emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs)

Emit a call to the unary function named 'Name' (e.g.

bool all_of(R &&range, UnaryPredicate P)

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

Value * simplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

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

Value * simplifySDivInst(Value *LHS, Value *RHS, bool IsExact, const SimplifyQuery &Q)

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

Value * simplifyMulInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

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

bool hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty, LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn)

Check whether the overloaded floating point function corresponding to Ty is available.

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 matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)

Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...

bool any_of(R &&range, UnaryPredicate P)

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

constexpr unsigned MaxAnalysisRecursionDepth

Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)

Attempt to constant fold a unary operation with the specified operand.

Value * simplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

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

Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)

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

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

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

Value * simplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

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

@ Mul

Product of integers.

@ And

Bitwise or logical AND of integers.

Value * simplifyUDivInst(Value *LHS, Value *RHS, bool IsExact, const SimplifyQuery &Q)

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

DWARFExpression::Operation Op

constexpr unsigned BitWidth

bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)

Return true if this function can prove that the instruction I will always transfer execution to one o...

Value * simplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

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

unsigned Log2(Align A)

Returns the log2 of the alignment.

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

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

bool isKnownNegation(const Value *X, const Value *Y, bool NeedNSW=false, bool AllowPoison=true)

Return true if the two given values are negation.

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

Returns true if the give value is known to be non-negative.

Value * simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

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

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

Implement std::swap in terms of BitVector swap.

bool isNonNegative() const

Returns true if this value is known to be non-negative.

unsigned countMinTrailingZeros() const

Returns the minimum number of trailing zero bits.

SimplifyQuery getWithInstruction(const Instruction *I) const