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;

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);

110 return Builder.CreateSelect(Cond, OtherOp, Neg);

111 }

112

113

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

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

118 return Builder.CreateSelect(Cond, Neg, OtherOp);

119 }

120

121

122

126 return Builder.CreateSelectFMF(Cond, OtherOp,

127 Builder.CreateFNegFMF(OtherOp, &I), &I);

128

129

130

134 return Builder.CreateSelectFMF(Cond, Builder.CreateFNegFMF(OtherOp, &I),

135 OtherOp, &I);

136

137 return nullptr;

138}

139

140

141

144 Value *X = Mul.getOperand(0), *Y = Mul.getOperand(1);

145 if (CommuteOperands)

147

148 const bool HasNSW = Mul.hasNoSignedWrap();

149 const bool HasNUW = Mul.hasNoUnsignedWrap();

150

151

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

155 return Builder.CreateShl(X, Z, Mul.getName(), HasNUW, PropagateNSW);

156 }

157

158

159

160

161

168 FrX = Builder.CreateFreeze(X, X->getName() + ".fr");

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

170 return Builder.CreateAdd(Shl, FrX, Mul.getName(), HasNUW, PropagateNSW);

171 }

172

173

174

175

176

177

181 FrX = Builder.CreateFreeze(X, X->getName() + ".fr");

182 Value *Shl = Builder.CreateShl(FrX, Z, "mulshl");

183 return Builder.CreateSub(Shl, FrX, Mul.getName());

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(),

193 SQ.getWithInstruction(&I)))

195

197 return &I;

198

200 return X;

201

203 return Phi;

204

207

208 Type *Ty = I.getType();

209 const unsigned BitWidth = Ty->getScalarSizeInBits();

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

258

259 {

261 const APInt *ShiftC;

262 const APInt *MulAP;

266 (*MulAP - 1).isPowerOf2() && *ShiftC == MulAP->logBase2()) {

267 Value *BinOp = Op0;

269

270

271 if (HasNUW && OpBO->getOpcode() == Instruction::AShr && OpBO->hasOneUse())

272 BinOp = Builder.CreateLShr(NewOp, ConstantInt::get(Ty, *ShiftC), "",

273 true);

274

275 auto *NewAdd = BinaryOperator::CreateAdd(NewOp, BinOp);

276 if (HasNSW && (HasNUW || OpBO->getOpcode() == Instruction::LShr ||

278 NewAdd->setHasNoSignedWrap(true);

279

280 NewAdd->setHasNoUnsignedWrap(HasNUW);

281 return NewAdd;

282 }

283 }

284

286

287

288 if (Value *NegOp0 =

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

293 false,

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

295 }

296

297

298

299

300

301

302

303 const APInt *NegPow2C;

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

308 unsigned ShiftAmt = NegPow2C->countr_zero();

309 if (ShiftAmt >= BitWidth - SrcWidth) {

311 Value *Z = Builder.CreateZExt(N, Ty, N->getName() + ".z");

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

313 }

314 }

315 }

316

318 return FoldedMul;

319

322

323

326

327

331

334 bool Op0NUW =

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

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

338 if (HasNUW && Op0NUW) {

339

341 NewMulBO->setHasNoUnsignedWrap();

342 BO->setHasNoUnsignedWrap();

343 }

344 return BO;

345 }

346 }

347

348

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

352

353 {

355

356 if (I.hasNoSignedWrap() &&

361 I, Builder.CreateBinaryIntrinsic(Intrinsic::abs,

364 }

365

366

371

372

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

377 NewMul->setHasNoSignedWrap();

378 return NewMul;

379 }

380

381

382

385

386

387

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

391 }

392

394

395

396

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

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

403 };

409 BOpc, X,

411 Op1));

412 }

413 }

414

415

416

417 {

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

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

422 Y = Op0;

424 }

425 Value *Neg = dyn_castNegVal(Y);

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

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

431

432

434 if (DivOp1 == Y)

437 }

438

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

440 : Instruction::SRem;

441

444 XFreeze = Builder.CreateFreeze(X, X->getName() + ".fr");

445 Value *Rem = Builder.CreateBinOp(RemOpc, XFreeze, DivOp1);

446 if (DivOp1 == Y)

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

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

449 }

450 }

451

452

453

454

455

456

457 if (Ty->isIntOrIntVectorTy(1) ||

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

461

466

467

468

469

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

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

476 }

477

478

479

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

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

486 }

487

488

489

494

495

496

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

501

504

508 }

509

510

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

517 }

518 }

519

520

521

522

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

528 }

529

530

534 }

535

536

537

546 }

547

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

549 return Ext;

550

552 return Res;

553

554

555

556

557

558

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

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

561

563 return Shl;

564 }

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

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

567

569 return Shl;

570 }

571

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

575 I.setHasNoSignedWrap(true);

576 }

577

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

580 I.setHasNoUnsignedWrap(true);

581 }

582

583 return Changed ? &I : nullptr;

584}

585

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

589 "Expected fmul or fdiv");

590

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

593

594

595

598

599

600

603

604

605

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

608 Value *XY = Builder.CreateBinOpFMF(Opcode, X, Y, &I);

610 Builder.CreateUnaryIntrinsic(Intrinsic::fabs, XY, &I, I.getName());

612 }

613

614 return nullptr;

615}

616

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

624

625 return NewPow;

626 };

627

629 unsigned Opcode = I.getOpcode();

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

631 "Unexpected opcode");

632

633

634

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

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

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

642 }

643 }

644

645

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

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

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

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

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

656 }

657

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

659

660

661

662

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

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

669 }

670

671

672

673

674

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

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

682 }

683 }

684

685 return nullptr;

686}

687

688

689

690

691

692

703 }

704

709 R2.insert(I);

710 }

711 }

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

713}

714

715

716

717

718

719

720

721

722

723

724

725

729

731 return false;

732

736

740 return false;

741

742

743

744

745

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

747 return false;

748

749

750

751

752

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

754 return false;

755

756

758

759

760

761

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

763 }))

764 return false;

765

766

768

769

770

771

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

773 });

774}

775

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

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

782

783

784

787

791

796 }

798

799

804

805

806

811 }

812

813

814

815

817

822 }

823 }

825

830 }

831 }

832 }

833

841

842 auto *NewFMul = Builder.CreateFMulFMF(X, Z, FMF);

844 }

845 }

846

847

848

849

853 Value *Sqrt = Builder.CreateUnaryIntrinsic(Intrinsic::sqrt, XY, &I);

855 }

856

857

858

859

860

861

862

863 if (I.hasNoSignedZeros() &&

867 if (I.hasNoSignedZeros() &&

871

872

873

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

875

876

880 }

881

885 }

886 }

887

888

889

893 Value *Y1 = Builder.CreateFAddFMF(Y, ConstantFP::get(I.getType(), 1.0), &I);

894 Value *Pow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, X, Y1, &I);

896 }

897

899 return FoldedPowi;

900

901 if (I.isOnlyUserOfAnyOperand()) {

902

905 auto *YZ = Builder.CreateFAddFMF(Y, Z, &I);

906 auto *NewPow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, X, YZ, &I);

908 }

909

912 auto *XZ = Builder.CreateFMulFMF(X, Z, &I);

913 auto *NewPow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, XZ, Y, &I);

915 }

916

917

921 Value *Exp = Builder.CreateUnaryIntrinsic(Intrinsic::exp, XY, &I);

923 }

924

925

929 Value *Exp2 = Builder.CreateUnaryIntrinsic(Intrinsic::exp2, XY, &I);

931 }

932 }

933

934

935

936

937

938

939

940

944 }

948 }

949

950 return nullptr;

951}

952

955 I.getFastMathFlags(),

956 SQ.getWithInstruction(&I)))

958

960 return &I;

961

963 return X;

964

966 return Phi;

967

969 return FoldedMul;

970

973

975 return R;

976

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

978 return R;

979

980

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

984

985

986

987

993 Op0 = Builder.CreateFNegFMF(Op0, &I);

994 CallInst *CopySign = Builder.CreateIntrinsic(Intrinsic::copysign,

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

997 }

998

999

1005

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

1007

1008

1009

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

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

1014 return SI;

1015 }

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

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

1020 return SI;

1021 }

1022 }

1023

1024

1027

1028 if (I.hasAllowReassoc())

1030 return FoldedMul;

1031

1032

1033 if (I.isFast()) {

1038 Y = Op1;

1039 }

1043 Y = Op0;

1044 }

1049 }

1050 }

1051

1052

1053

1054

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

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

1060

1061

1067

1068

1069

1070 if (!Result->hasNoNaNs())

1071 Result->setHasNoInfs(false);

1072 return Result;

1073 }

1074

1075

1076 if (I.hasAllowContract() &&

1080 auto *Sin = Builder.CreateUnaryIntrinsic(Intrinsic::sin, X, &I);

1081 if (auto *Metadata = I.getMetadata(LLVMContext::MD_fpmath)) {

1082 Sin->setMetadata(LLVMContext::MD_fpmath, Metadata);

1083 }

1085 }

1086

1087 return nullptr;

1088}

1089

1090

1091

1092

1095 if (SI)

1096 return false;

1097

1098 int NonNullOperand;

1100

1101 NonNullOperand = 2;

1103

1104 NonNullOperand = 1;

1105 else

1106 return false;

1107

1108

1110

1111

1112

1113

1114

1115

1116

1117

1118

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

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

1121 return true;

1122

1123

1126 while (BBI != BBFront) {

1127 --BBI;

1128

1129

1131 break;

1132

1133

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

1135 if (Op == SI) {

1138 } else if (Op == SelectCond) {

1142 }

1143 }

1144

1145

1146 if (&*BBI == SI)

1147 SI = nullptr;

1148 if (&*BBI == SelectCond)

1149 SelectCond = nullptr;

1150

1151

1152 if (!SelectCond && SI)

1153 break;

1154

1155 }

1156 return true;

1157}

1158

1159

1161 bool IsSigned) {

1162 bool Overflow;

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

1164 return Overflow;

1165}

1166

1167

1169 bool IsSigned) {

1171

1172

1174 return false;

1175

1176

1178 return false;

1179

1181 if (IsSigned)

1183 else

1185

1187}

1188

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

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

1192 "Expected integer divide");

1193

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

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

1196 Type *Ty = I.getType();

1197

1199

1200

1201

1204

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

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

1209

1210

1211 if (!IsSigned && HasNUW)

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

1213

1214

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

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

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

1218 }

1219 }

1220

1221

1222

1227

1228

1229

1230

1231 if (!IsSigned &&

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

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

1234 Shl1->hasNoSignedWrap())))

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

1236

1237

1238

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

1240 Shl1->hasNoUnsignedWrap())

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

1242 }

1243

1244

1245

1250

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

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

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

1254

1255

1256 Value *Dividend = Builder.CreateShl(

1257 One, Y, "shl.dividend",

1258 true,

1259

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

1261 : Shl0->hasNoSignedWrap());

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

1263 }

1264 }

1265

1266 return nullptr;

1267}

1268

1269

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

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

1273

1274

1275

1277 Type *Ty = I.getType();

1279 if (Op1C && VTy) {

1280 unsigned NumElts = VTy->getNumElements();

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

1285 }

1286 }

1287

1289 return Phi;

1290

1291

1294

1295

1297 return &I;

1298

1299

1300

1301

1302

1306 true))

1307 return R;

1308 }

1309

1310 return nullptr;

1311}

1312

1313

1314

1315

1316

1319 return Res;

1320

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

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

1323 Type *Ty = I.getType();

1324

1325 const APInt *C2;

1328 const APInt *C1;

1329

1330

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

1337 }

1338

1342

1343

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

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

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

1348 return NewDiv;

1349 }

1350

1351

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

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

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

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

1358 return Mul;

1359 }

1360 }

1361

1368

1369

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

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

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

1374 return BO;

1375 }

1376

1377

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

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

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

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

1384 return Mul;

1385 }

1386 }

1387

1388

1389

1390

1391

1392 if (IsSigned &&

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

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

1397 }

1398 if (!IsSigned &&

1401 return BinaryOperator::CreateNUWAdd(X,

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

1403 }

1404

1405 if (!C2->isZero())

1407 return FoldedDiv;

1408 }

1409

1411 assert(!Ty->isIntOrIntVectorTy(1) && "i1 divide not removed?");

1412 if (IsSigned) {

1413

1414

1415

1416 Value *F1 = Op1;

1418 F1 = Builder.CreateFreeze(Op1, Op1->getName() + ".fr");

1420 Value *Cmp = Builder.CreateICmpULT(Inc, ConstantInt::get(Ty, 3));

1422 } else {

1423

1424

1425 return new ZExtInst(Builder.CreateICmpEQ(Op1, Op0), Ty);

1426 }

1427 }

1428

1429

1431 return &I;

1432

1433

1439

1440

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

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

1446

1447

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

1454 return &I;

1455 }

1456 }

1457

1458

1459

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

1464 Instruction *NewDiv = BinaryOperator::CreateUDiv(

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

1467 return NewDiv;

1468 }

1469

1472

1473

1474

1475

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

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

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

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

1485

1486

1487 if (NewDiv) {

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

1489 return NewDiv;

1490 }

1491 }

1492

1493

1497

1500 auto OB1HasNUW =

1502 const APInt *C1, *C2;

1503 if (IsSigned && OB0HasNSW) {

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

1506 }

1507 if (!IsSigned && OB0HasNUW) {

1508 if (OB1HasNUW)

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

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

1512 }

1513 return nullptr;

1514 };

1515

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

1518 return Val;

1519 }

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

1522 return Val;

1523 }

1524 }

1525 return nullptr;

1526}

1527

1529 bool DoFold) {

1531 if (!DoFold)

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

1533 return Fn();

1534 };

1535

1536

1537

1538

1540 return IfFold([&]() {

1542 if (C)

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

1544 return C;

1545 });

1546

1547

1549 return nullptr;

1550

1551

1552

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

1557

1558

1559

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

1564 return IfFold([&]() {

1565 return Builder.CreateTrunc(LogX, Op->getType(), "",

1566 TI->hasNoUnsignedWrap());

1567 });

1568 }

1569

1570

1571

1574

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

1577 return IfFold([&]() { return Builder.CreateAdd(LogX, Y); });

1578 }

1579

1580

1581

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

1586 return IfFold([&]() { return Builder.CreateSub(LogX, Y); });

1587 }

1588

1589

1590

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

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

1596 }

1597

1598

1599

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

1602 if (Value *LogY =

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

1604 return IfFold([&]() {

1605 return Builder.CreateSelect(SI->getOperand(0), LogX, LogY);

1606 });

1607

1608

1609

1612

1613

1615 false, DoFold))

1617 false, DoFold))

1618 return IfFold([&]() {

1619 return Builder.CreateBinaryIntrinsic(MinMax->getIntrinsicID(), LogX,

1620 LogY);

1621 });

1622 }

1623

1624 return nullptr;

1625}

1626

1627

1628

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

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

1634 Type *Ty = I.getType();

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

1638

1639

1641 return new ZExtInst(NarrowOp, Ty);

1642 }

1643

1648

1650 if (!TruncC)

1651 return nullptr;

1652

1653

1654

1656 }

1659

1661 if (!TruncC)

1662 return nullptr;

1663

1664

1665

1667 }

1668

1669 return nullptr;

1670}

1671

1674 SQ.getWithInstruction(&I)))

1676

1678 return X;

1679

1680

1682 return Common;

1683

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

1686 const APInt *C1, *C2;

1688

1689 bool Overflow;

1691 if (!Overflow) {

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

1695 if (IsExact)

1697 return BO;

1698 }

1699 }

1700

1701

1702

1703 Type *Ty = I.getType();

1705 Value *Cmp = Builder.CreateICmpUGE(Op0, Op1);

1707 }

1708

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

1712 }

1713

1715 return NarrowDiv;

1716

1718

1719

1720

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

1726 return Lshr;

1727 }

1728

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

1730

1732 return Log2;

1733

1734

1736

1737

1738

1739 return Builder.CreateBinaryIntrinsic(Intrinsic::cttz, Denom,

1741

1742 return nullptr;

1743 };

1744

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

1747 I, Builder.CreateLShr(Op0, Res, I.getName(), I.isExact()));

1748

1749 return nullptr;

1750}

1751

1754 SQ.getWithInstruction(&I)))

1756

1758 return X;

1759

1760

1762 return Common;

1763

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

1765 Type *Ty = I.getType();

1767

1768

1772

1773

1775 return new ZExtInst(Builder.CreateICmpEQ(Op0, Op1), Ty);

1776

1777 if (I.isExact()) {

1778

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

1782 }

1783

1784

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

1788

1789

1793 Value *Ashr = Builder.CreateAShr(Op0, C, I.getName() + ".neg", true);

1795 }

1796 }

1797

1798 const APInt *Op1C;

1800

1801

1802

1807

1808

1809

1810

1811

1814 Value *NarrowOp = Builder.CreateSDiv(Op0Src, NarrowDivisor);

1815 return new SExtInst(NarrowOp, Ty);

1816 }

1817

1818

1819

1820

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

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

1825 return BO;

1826 }

1827 }

1828

1829

1833 Builder.CreateSDiv(X, Y, I.getName(), I.isExact()));

1834

1835

1836

1843 }

1844

1846 if (I.isExact() &&

1849 I.setIsExact();

1850 return &I;

1851 }

1852

1854

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

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

1858 return BO;

1859 }

1860

1862

1863

1866 Value *Shr = Builder.CreateLShr(Op0, CNegLog2, I.getName(), I.isExact());

1868 }

1869

1871

1872

1873

1874

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

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

1877 return BO;

1878 }

1879 }

1880

1881

1884 Value *Cond = Builder.CreateICmpEQ(Op0, ConstantInt::get(Ty, MinVal));

1887 }

1888 return nullptr;

1889}

1890

1891

1895 return nullptr;

1896

1897

1903

1904

1905

1906 if (I.hasNoNaNs() &&

1910 CallInst *CopySign = B.CreateIntrinsic(

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

1915 }

1916

1917

1918

1919

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

1921 return nullptr;

1922

1923

1924

1925

1926

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

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

1930 return nullptr;

1931

1932

1934}

1935

1936

1940 return nullptr;

1941

1942

1948

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

1950 return nullptr;

1951

1952

1953 Constant *C2, *NewC = nullptr;

1955

1958

1960 }

1961

1962

1963

1964

1966 return nullptr;

1967

1969}

1970

1971

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

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

1977 I.hasAllowReciprocal())

1978 return nullptr;

1979

1980

1981

1982

1983

1986 switch (IID) {

1987 case Intrinsic::pow:

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

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

1990 break;

1991 case Intrinsic::powi: {

1992

1993

1994

1995

1996

1997 if (I.hasNoInfs())

1998 return nullptr;

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

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

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

2002 Value *Pow = Builder.CreateIntrinsic(IID, Tys, Args, &I);

2004 }

2005 case Intrinsic::exp:

2006 case Intrinsic::exp2:

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

2008 break;

2009 default:

2010 return nullptr;

2011 }

2012 Value *Pow = Builder.CreateIntrinsic(IID, I.getType(), Args, &I);

2014}

2015

2016

2017

2020

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

2022 return nullptr;

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

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

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

2027 return nullptr;

2028

2031 if (!DivOp)

2032 return nullptr;

2034 return nullptr;

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

2036 !DivOp->hasOneUse())

2037 return nullptr;

2038 Value *SwapDiv = Builder.CreateFDivFMF(Z, Y, DivOp);

2039 Value *NewSqrt =

2040 Builder.CreateUnaryIntrinsic(II->getIntrinsicID(), SwapDiv, II);

2042}

2043

2044

2045

2046

2047

2048

2049

2050

2051

2052

2053

2054

2055

2056

2062

2063 B.SetInsertPoint(X);

2064

2065

2066

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

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

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

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

2075 R1FMF &= I->getFastMathFlags();

2078 }

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

2080 FDiv->copyFastMathFlags(R1FMF);

2081

2082

2083

2084

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

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

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

2092 R2FMF &= I->getFastMathFlags();

2095 }

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

2097 FSqrt->copyFastMathFlags(R2FMF);

2098

2100

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

2104 } else

2106 FMul->copyMetadata(*X);

2110}

2111

2113 Module *M = I.getModule();

2114

2116 I.getFastMathFlags(),

2117 SQ.getWithInstruction(&I)))

2119

2121 return X;

2122

2124 return Phi;

2125

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

2127 return R;

2128

2130 return R;

2131

2133 return R;

2134

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

2136

2137

2138

2139

2140

2141

2142

2143

2144

2145

2146

2151 return D;

2152 }

2153

2157 return R;

2158

2162 return R;

2163

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

2168

2171 }

2174

2177 }

2178

2179

2180

2181

2182

2183

2186 }

2187

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

2189

2190

2194 bool IsCot =

2197

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

2199 LibFunc_tanf, LibFunc_tanl)) {

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

2203 AttributeList Attrs =

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

2206 LibFunc_tanl, B, Attrs);

2207 if (IsCot)

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

2210 }

2211 }

2212

2213

2214

2215

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

2221 return &I;

2222 }

2223

2224

2225

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

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

2232 }

2233

2235 return Mul;

2236

2238 return Mul;

2239

2240

2241 if (I.hasAllowReassoc() &&

2245 Builder.CreateFAddFMF(Y, ConstantFP::get(I.getType(), -1.0), &I);

2246 Value *Pow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, Op1, Y1, &I);

2248 }

2249

2251 return FoldedPowi;

2252

2253 return nullptr;

2254}

2255

2256

2257

2258

2259

2260

2261

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

2266 bool ShiftByX = false;

2267

2268

2270 bool &PreserveNSW) -> bool {

2271 const APInt *Tmp = nullptr;

2274 C = *Tmp;

2278

2280 }

2281 if (Tmp != nullptr)

2282 return true;

2283

2284

2285 V = nullptr;

2286 return false;

2287 };

2288

2290 const APInt *Tmp = nullptr;

2293 C = *Tmp;

2294 return true;

2295 }

2296

2297

2298 V = nullptr;

2299 return false;

2300 };

2301

2302 bool Op0PreserveNSW = true, Op1PreserveNSW = true;

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

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

2305

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

2307 ShiftByX = true;

2308 } else {

2309 return nullptr;

2310 }

2311

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

2313

2315

2316

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

2319 bool BO0NoWrap = IsSRem ? BO0HasNSW : BO0HasNUW;

2320

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

2322

2323

2324

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

2327

2328

2329

2330

2331 auto CreateMulOrShift =

2333 Value *RemSimplification =

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

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

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

2337 };

2338

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

2342 bool BO1NoWrap = IsSRem ? BO1HasNSW : BO1HasNUW;

2343

2344

2345

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

2348

2351 return BO;

2352 }

2353

2354

2355

2356

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

2361 return BO;

2362 }

2363

2364 return nullptr;

2365}

2366

2367

2368

2369

2370

2373 return Res;

2374

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

2376

2381 return R;

2383 const APInt *Op1Int;

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

2387

2388

2389

2391 return NV;

2392 }

2393 }

2394

2395

2397 return &I;

2398 }

2399 }

2400

2402 return R;

2403

2404 return nullptr;

2405}

2406

2409 SQ.getWithInstruction(&I)))

2411

2413 return X;

2414

2416 return common;

2417

2419 return NarrowRem;

2420

2421

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

2423 Type *Ty = I.getType();

2425

2426

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

2430 }

2431

2432

2434 Value *Cmp = Builder.CreateICmpNE(Op1, ConstantInt::get(Ty, 1));

2436 }

2437

2438

2439

2441 Value *F0 = Op0;

2443 F0 = Builder.CreateFreeze(Op0, Op0->getName() + ".fr");

2444 Value *Cmp = Builder.CreateICmpULT(F0, Op1);

2447 }

2448

2449

2450

2451

2452

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

2455 Value *FrozenOp0 = Op0;

2457 FrozenOp0 = Builder.CreateFreeze(Op0, Op0->getName() + ".frozen");

2461 }

2462

2463

2468 Value *FrozenOp0 = Op0;

2470 FrozenOp0 = Builder.CreateFreeze(Op0, Op0->getName() + ".frozen");

2471 Value *Cmp = Builder.CreateICmpEQ(FrozenOp0, Op1);

2473 }

2474 }

2475

2476 return nullptr;

2477}

2478

2481 SQ.getWithInstruction(&I)))

2483

2485 return X;

2486

2487

2489 return Common;

2490

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

2492 {

2494

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

2497 }

2498

2499

2503

2504

2505

2508

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

2510 }

2511

2512

2516

2517 bool hasNegative = false;

2518 bool hasMissing = false;

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

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

2521 if (!Elt) {

2522 hasMissing = true;

2523 break;

2524 }

2525

2527 if (RHS->isNegative())

2528 hasNegative = true;

2529 }

2530

2531 if (hasNegative && !hasMissing) {

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

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

2536 if (RHS->isNegative())

2538 }

2539 }

2540

2542 if (NewRHSV != C)

2544 }

2545 }

2546

2547 return nullptr;

2548}

2549

2552 I.getFastMathFlags(),

2553 SQ.getWithInstruction(&I)))

2555

2557 return X;

2558

2560 return Phi;

2561

2562 return nullptr;

2563}

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

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 Instruction * convertFSqrtDivIntoFMul(CallInst *CI, Instruction *X, const SmallPtrSetImpl< Instruction * > &R1, const SmallPtrSetImpl< Instruction * > &R2, InstCombiner::BuilderTy &B, InstCombinerImpl *IC)

Definition InstCombineMulDivRem.cpp:2058

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

Definition InstCombineMulDivRem.cpp:2262

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

Definition InstCombineMulDivRem.cpp:1629

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.

Definition InstCombineMulDivRem.cpp:47

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

Definition InstCombineMulDivRem.cpp:693

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

Definition InstCombineMulDivRem.cpp:100

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

Definition InstCombineMulDivRem.cpp:726

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

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

Definition InstCombineMulDivRem.cpp:1972

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.

Definition InstCombineMulDivRem.cpp:1160

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

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

Definition InstCombineMulDivRem.cpp:142

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.

Definition InstCombineMulDivRem.cpp:1168

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.

Definition InstCombineMulDivRem.cpp:2018

static Instruction * foldFDivConstantDividend(BinaryOperator &I)

Remove negation and try to reassociate constant math.

Definition InstCombineMulDivRem.cpp:1937

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

Definition InstCombineMulDivRem.cpp:1189

This file provides the interface for the instcombine pass implementation.

static bool hasNoSignedWrap(BinaryOperator &I)

static bool hasNoUnsignedWrap(BinaryOperator &I)

uint64_t IntrinsicInst * II

const SmallVectorImpl< MachineOperand > & Cond

This file defines the SmallPtrSet class.

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")

Class for arbitrary precision integers.

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

LLVM_ABI APInt udiv(const APInt &RHS) const

Unsigned division operation.

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

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

unsigned getSignificantBits() const

Get the minimum bit size for this signed APInt.

unsigned logBase2() const

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

const Function * getParent() const

Return the enclosing method, or null if none.

InstListType::iterator iterator

Instruction iterators...

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

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

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 LLVM_ABI 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 LLVM_ABI CastInst * CreateZExtOrBitCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Create a ZExt or BitCast cast instruction.

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

static Type * makeCmpResultType(Type *opnd_type)

Create a result type for fcmp/icmp.

@ ICMP_ULT

unsigned less than

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

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

static LLVM_ABI 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 LLVM_ABI Constant * getInfinity(Type *Ty, bool Negative=false)

This is the shared class of boolean and integer constants.

static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)

static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)

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

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

This is an important base class in LLVM.

static LLVM_ABI Constant * getAllOnesValue(Type *Ty)

LLVM_ABI bool isNormalFP() const

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

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 isNotMinSignedValue() const

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

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.

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

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

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

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

Instruction * visitMul(BinaryOperator &I)

Definition InstCombineMulDivRem.cpp:189

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)

Definition InstCombineMulDivRem.cpp:1672

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)

Definition InstCombineMulDivRem.cpp:2407

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

InstCombinerImpl(InstructionWorklist &Worklist, BuilderTy &Builder, Function &F, AAResults *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, TargetTransformInfo &TTI, DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI, ProfileSummaryInfo *PSI, const DataLayout &DL, ReversePostOrderTraversal< BasicBlock * > &RPOT)

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

Take the exact integer log2 of the value.

Definition InstCombineMulDivRem.cpp:1528

Instruction * visitSRem(BinaryOperator &I)

Definition InstCombineMulDivRem.cpp:2479

Instruction * visitFDiv(BinaryOperator &I)

Definition InstCombineMulDivRem.cpp:2112

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

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

bool simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I)

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

Definition InstCombineMulDivRem.cpp:1093

Instruction * eraseInstFromFunction(Instruction &I) override

Combiner aware instruction erasure.

Instruction * commonIDivRemTransforms(BinaryOperator &I)

Common integer divide/remainder transforms.

Definition InstCombineMulDivRem.cpp:1270

Value * tryGetLog2(Value *Op, bool AssumeNonZero)

Instruction * commonIDivTransforms(BinaryOperator &I)

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

Definition InstCombineMulDivRem.cpp:1317

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)

Definition InstCombineMulDivRem.cpp:2550

bool SimplifyDemandedInstructionBits(Instruction &Inst)

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

Instruction * visitFMul(BinaryOperator &I)

Definition InstCombineMulDivRem.cpp:953

Instruction * foldFMulReassoc(BinaryOperator &I)

Definition InstCombineMulDivRem.cpp:776

Instruction * foldVectorBinop(BinaryOperator &Inst)

Canonicalize the position of binops relative to shufflevector.

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

Instruction * foldPowiReassoc(BinaryOperator &I)

Definition InstCombineMulDivRem.cpp:617

Instruction * visitSDiv(BinaryOperator &I)

Definition InstCombineMulDivRem.cpp:1752

Instruction * commonIRemTransforms(BinaryOperator &I)

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

Definition InstCombineMulDivRem.cpp:2371

const DataLayout & getDataLayout() const

IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy

An IRBuilder that automatically inserts new instructions into the worklist.

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.

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

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

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

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

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

LLVM_ABI Instruction * clone() const

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

LLVM_ABI void setHasNoUnsignedWrap(bool b=true)

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

LLVM_ABI bool hasNoNaNs() const LLVM_READONLY

Determine whether the no-NaNs flag is set.

LLVM_ABI bool hasNoInfs() const LLVM_READONLY

Determine whether the no-infs flag is set.

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 setHasNoSignedWrap(bool b=true)

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

LLVM_ABI bool isExact() const LLVM_READONLY

Determine whether the exact flag is set.

LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY

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

LLVM_ABI void setIsExact(bool b=true)

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

LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY

Determine whether the allow-reassociation flag is set.

A wrapper class for inspecting calls to intrinsic functions.

static LLVM_ABI 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 LLVM_ABI 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, const 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.

LLVM_ABI 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()

LLVM_ABI bool hasNUses(unsigned N) const

Return true if this Value has exactly N uses.

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.

This class represents zero extension of integer types.

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

self_iterator getIterator()

#define llvm_unreachable(msg)

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

@ C

The default llvm calling convention, compatible with C.

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)

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)

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.

AllowReassoc_match< T > m_AllowReassoc(const T &SubPattern)

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

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

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

Matches Trunc.

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

Match APInt while allowing poison in splat vector constants.

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.

BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)

Matches logical shift operations.

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.

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.

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.

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()...

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.

match_immconstant_ty m_ImmConstant()

Match an arbitrary immediate Constant and ignore it.

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.

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)

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

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

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

decltype(auto) dyn_cast(const From &Val)

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

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

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

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

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

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

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.

LLVM_ABI 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

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

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

LLVM_ABI Constant * getLosslessUnsignedTrunc(Constant *C, Type *DestTy, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)

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

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

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

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 Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)

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

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

@ Sub

Subtraction of integers.

LLVM_ABI 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

LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)

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

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

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

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

Return true if the two given values are negation.

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

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

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