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

1

2

3

4

5

6

7

8

9

10

11

12

29#include

30#include

31

32using namespace llvm;

34

35#define DEBUG_TYPE "instcombine"

36

38

42

43

44

46 return Result;

47

50

51

54 unsigned Opc = I->getOpcode();

55 switch (Opc) {

56 case Instruction::Add:

57 case Instruction::Sub:

58 case Instruction::Mul:

59 case Instruction::And:

60 case Instruction::Or:

61 case Instruction::Xor:

62 case Instruction::AShr:

63 case Instruction::LShr:

64 case Instruction::Shl:

65 case Instruction::UDiv:

66 case Instruction::URem: {

68 Processed);

70 Processed);

72 if (Opc == Instruction::LShr || Opc == Instruction::AShr)

74 break;

75 }

76 case Instruction::Trunc:

77 case Instruction::ZExt:

78 case Instruction::SExt:

79

80

81

82 if (I->getOperand(0)->getType() == Ty)

83 return I->getOperand(0);

84

85

86

88 Opc == Instruction::SExt);

89 break;

90 case Instruction::Select: {

92 IC, Processed);

94 IC, Processed);

96 break;

97 }

98 case Instruction::PHI: {

105 }

106 Res = NPN;

107 break;

108 }

109 case Instruction::FPToUI:

110 case Instruction::FPToSI:

112 I->getOperand(0), Ty);

113 break;

114 case Instruction::Call:

116 switch (II->getIntrinsicID()) {

117 default:

119 case Intrinsic::vscale: {

121 I->getModule(), Intrinsic::vscale, {Ty});

123 break;

124 }

125 }

126 }

127 break;

128 case Instruction::ShuffleVector: {

131 auto *FixedTy = VectorType::get(ScalarTy, VTy->getElementCount());

138 break;

139 }

140 default:

141

143 }

144

147

148

149

150 if (!V->hasOneUse())

151 Processed[V] = Result;

152

153 return Result;

154}

155

156

157

163

165InstCombinerImpl::isEliminableCastPair(const CastInst *CI1,

170

173 Type *SrcIntPtrTy =

175 Type *DstIntPtrTy =

178 DstTy, &DL);

179

180

181

182 if ((Res == Instruction::IntToPtr && SrcTy != DstIntPtrTy) ||

183 (Res == Instruction::PtrToInt && DstTy != SrcIntPtrTy))

184 Res = 0;

185

187}

188

189

193

197

198

201

202

203 auto *Res = CastInst::Create(NewOpc, CSrc->getOperand(0), Ty);

204

205 if (CSrc->hasOneUse())

207 return Res;

208 }

209 }

210

212

213

214

215

216

218 if (!Cmp || Cmp->getOperand(0)->getType() != Sel->getType() ||

219 (CI.getOpcode() == Instruction::Trunc &&

221

222

223

224 if (CI.getOpcode() != Instruction::BitCast ||

228 return NV;

229 }

230 }

231 }

232 }

233

234

236

237

238 if (!Src->getType()->isIntegerTy() || !CI.getType()->isIntegerTy() ||

241 return NV;

242 }

243

244

245

246

247

251

254 if (SrcTy && DestTy &&

255 SrcTy->getNumElements() == DestTy->getNumElements() &&

256 SrcTy->getPrimitiveSizeInBits() == DestTy->getPrimitiveSizeInBits()) {

259 }

260 }

261

262 return nullptr;

263}

264

265namespace {

266

267

268

269class TypeEvaluationHelper {

270public:

271

272

273

274 [[nodiscard]] static bool canEvaluateTruncated(Value *V, Type *Ty,

277

278

279

280 [[nodiscard]] static bool canEvaluateZExtd(Value *V, Type *Ty,

281 unsigned &BitsToClear,

284

285

286

287

288 [[nodiscard]] static bool canEvaluateSExtd(Value *V, Type *Ty);

289

290private:

291

292

293 [[nodiscard]] static bool canAlwaysEvaluateInType(Value *V, Type *Ty);

294

295

296 [[nodiscard]] bool allPendingVisited() const {

298 [this](Value *V) { return Visited.contains(V); });

299 }

300

301

302

303 [[nodiscard]] bool

305 llvm::function_ref<bool(Value *, Type *Type)> Pred) {

306 if (canAlwaysEvaluateInType(V, Ty))

307 return true;

308

310

311 if (I == nullptr)

312 return false;

313

314

315 const auto [It, Inserted] = Visited.insert({V, false});

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331 if (!Inserted)

332 return It->getSecond();

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393 if (I->hasOneUse())

395

396 const bool Result = Pred(V, Ty);

397

398

401 }

402

403

404

405 [[nodiscard]] bool canNotEvaluateInType(Value *V, Type *Ty);

406

407 [[nodiscard]] bool canEvaluateTruncatedImpl(Value *V, Type *Ty,

408 InstCombinerImpl &IC,

409 Instruction *CxtI);

410 [[nodiscard]] bool canEvaluateTruncatedPred(Value *V, Type *Ty,

411 InstCombinerImpl &IC,

412 Instruction *CxtI);

413 [[nodiscard]] bool canEvaluateZExtdImpl(Value *V, Type *Ty,

414 unsigned &BitsToClear,

415 InstCombinerImpl &IC,

416 Instruction *CxtI);

417 [[nodiscard]] bool canEvaluateSExtdImpl(Value *V, Type *Ty);

418 [[nodiscard]] bool canEvaluateSExtdPred(Value *V, Type *Ty);

419

420

421

422 SmallDenseMap<Value *, bool, 8> Visited;

423

424

425 SmallVector<Value *, 8> Pending;

426};

427

428}

429

430

431

432bool TypeEvaluationHelper::canAlwaysEvaluateInType(Value *V, Type *Ty) {

435

438 X->getType() == Ty)

439 return true;

440

441 return false;

442}

443

444

445

446bool TypeEvaluationHelper::canNotEvaluateInType(Value *V, Type *Ty) {

448 return true;

449

450

451 if (V->hasOneUse())

452 return true;

453

454 return false;

455}

456

457

458

459

460

461

462

463

464

465

466

467

468bool TypeEvaluationHelper::canEvaluateTruncated(Value *V, Type *Ty,

471 TypeEvaluationHelper TYH;

472 return TYH.canEvaluateTruncatedImpl(V, Ty, IC, CxtI) &&

473

474

475 TYH.allPendingVisited();

476}

477

478bool TypeEvaluationHelper::canEvaluateTruncatedImpl(Value *V, Type *Ty,

481 return canEvaluate(V, Ty, [this, &IC, CxtI](Value *V, Type *Ty) {

482 return canEvaluateTruncatedPred(V, Ty, IC, CxtI);

483 });

484}

485

486bool TypeEvaluationHelper::canEvaluateTruncatedPred(Value *V, Type *Ty,

490 Type *OrigTy = V->getType();

491 switch (I->getOpcode()) {

492 case Instruction::Add:

493 case Instruction::Sub:

494 case Instruction::Mul:

495 case Instruction::And:

496 case Instruction::Or:

497 case Instruction::Xor:

498

499 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&

500 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);

501

502 case Instruction::UDiv:

503 case Instruction::URem: {

504

507 assert(BitWidth < OrigBitWidth && "Unexpected bitwidths!");

509

510

513 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&

514 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);

515 }

516 break;

517 }

518 case Instruction::Shl: {

519

520

525 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&

526 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);

527 break;

528 }

529 case Instruction::LShr: {

530

531

532

533

534

541

542

544 auto DemandedBits = Trunc->getType()->getScalarSizeInBits();

546 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&

547 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);

548 }

550 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&

551 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);

552 }

553 break;

554 }

555 case Instruction::AShr: {

556

557

558

559

560

565 unsigned ShiftedBits = OrigBitWidth - BitWidth;

568 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&

569 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);

570 break;

571 }

572 case Instruction::Trunc:

573

574 return true;

575 case Instruction::ZExt:

576 case Instruction::SExt:

577

578

579 return true;

580 case Instruction::Select: {

582 return canEvaluateTruncatedImpl(SI->getTrueValue(), Ty, IC, CxtI) &&

583 canEvaluateTruncatedImpl(SI->getFalseValue(), Ty, IC, CxtI);

584 }

585 case Instruction::PHI: {

586

587

588

592 return canEvaluateTruncatedImpl(IncValue, Ty, IC, CxtI);

593 });

594 }

595 case Instruction::FPToUI:

596 case Instruction::FPToSI: {

597

598

599

603 Semantics, I->getOpcode() == Instruction::FPToSI);

605 }

606 case Instruction::ShuffleVector:

607 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&

608 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);

609

610 default:

611

612 break;

613 }

614

615 return false;

616}

617

618

619

620

621

622

623

629 return nullptr;

630

631 Value *VecInput = nullptr;

637 return nullptr;

638

640 unsigned VecWidth = VecType->getPrimitiveSizeInBits();

642 unsigned ShiftAmount = ShiftVal ? ShiftVal->getZExtValue() : 0;

643

644 if ((VecWidth % DestWidth != 0) || (ShiftAmount % DestWidth != 0))

645 return nullptr;

646

647

648

649 unsigned NumVecElts = VecWidth / DestWidth;

650 if (VecType->getElementType() != DestType) {

653 }

654

655 unsigned Elt = ShiftAmount / DestWidth;

657 Elt = NumVecElts - 1 - Elt;

658

660}

661

662

663

664

665

666

667

668

669

670

671

672

673

677 Type *SrcType = Src->getType();

679

680

681

683 unsigned DstBits = DstType->getScalarSizeInBits();

684 unsigned TruncRatio = SrcBits / DstBits;

685 if ((SrcBits % DstBits) != 0)

686 return nullptr;

687

690 const APInt *ShiftAmount = nullptr;

695 return nullptr;

696

698 auto VecElts = VecOpTy->getElementCount();

699

700 uint64_t BitCastNumElts = VecElts.getKnownMinValue() * TruncRatio;

703 ? (VecOpIdx + 1) * TruncRatio - 1

704 : VecOpIdx * TruncRatio;

705

706

707 if (ShiftAmount) {

708

709

710 if (ShiftAmount->uge(SrcBits) || ShiftAmount->urem(DstBits) != 0)

711 return nullptr;

712

715 : (NewIdx + IdxOfs);

716 }

717

718 assert(BitCastNumElts <= std::numeric_limits<uint32_t>::max() &&

719 NewIdx <= std::numeric_limits<uint32_t>::max() && "overflow 32-bits");

720

721 auto *BitCastTo =

722 VectorType::get(DstType, BitCastNumElts, VecElts.isScalable());

725}

726

727

728

732 "Don't narrow to an illegal scalar type");

733

734

735

740 return nullptr;

741

742

743

744 BinaryOperator *Or0, *Or1;

746 return nullptr;

747

748 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;

752 return nullptr;

753

754

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

759 }

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

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

763

764

765

766 auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * {

767

768

769

770

771 unsigned MaxShiftAmountWidth = Log2_32(NarrowWidth);

772 APInt HiBitMask = ~APInt::getLowBitsSet(WideWidth, MaxShiftAmountWidth);

775 return L;

776

777

778

779 if (ShVal0 != ShVal1)

780 return nullptr;

781

782

783

785 unsigned Mask = Width - 1;

788 return X;

789

790

793 return X;

794

795 return nullptr;

796 };

797

798 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, NarrowWidth);

799 bool IsFshl = true;

800 if (!ShAmt) {

801 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, NarrowWidth);

802 IsFshl = false;

803 }

804 if (!ShAmt)

805 return nullptr;

806

807

808

809

812 return nullptr;

813

814

815

816

817

818

819 Value *NarrowShAmt = Builder.CreateZExtOrTrunc(ShAmt, DestTy);

820

822 X = Y = Builder.CreateTrunc(ShVal0, DestTy);

823 if (ShVal0 != ShVal1)

824 Y = Builder.CreateTrunc(ShVal1, DestTy);

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

829}

830

831

832

838

839 if (isa<VectorType>(SrcTy) && !shouldChangeType(SrcTy, DestTy))

840 return nullptr;

841

842 BinaryOperator *BinOp;

844 return nullptr;

845

849 case Instruction::And:

850 case Instruction::Or:

851 case Instruction::Xor:

852 case Instruction::Add:

853 case Instruction::Sub:

854 case Instruction::Mul: {

857

859 Value *TruncX = Builder.CreateTrunc(BinOp1, DestTy);

861 }

863

865 Value *TruncX = Builder.CreateTrunc(BinOp0, DestTy);

867 }

870

871 Value *NarrowOp1 = Builder.CreateTrunc(BinOp1, DestTy);

873 }

875

876 Value *NarrowOp0 = Builder.CreateTrunc(BinOp0, DestTy);

878 }

879 break;

880 }

881 case Instruction::LShr:

882 case Instruction::AShr: {

883

887 unsigned MaxShiftAmt = SrcWidth - DestWidth;

888

889

891 APInt(SrcWidth, MaxShiftAmt)))) {

893 bool IsExact = OldShift->isExact();

895 true, DL)) {

898 OldShift->getOpcode() == Instruction::AShr

899 ? Builder.CreateAShr(A, ShAmt, OldShift->getName(), IsExact)

900 : Builder.CreateLShr(A, ShAmt, OldShift->getName(), IsExact);

902 }

903 }

904 }

905 break;

906 }

907 default: break;

908 }

909

910 if (Instruction *NarrowOr = narrowFunnelShift(Trunc))

911 return NarrowOr;

912

913 return nullptr;

914}

915

916

917

918

922 if (Shuf && Shuf->hasOneUse() && match(Shuf->getOperand(1), m_Undef()) &&

923 all_equal(Shuf->getShuffleMask()) &&

926 ->getElementCount())) {

927

928

931 Value *NarrowOp = Builder.CreateTrunc(Shuf->getOperand(0), NewTruncTy);

933 }

934

935 return nullptr;

936}

937

938

939

940

941

942

946 assert((Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) &&

947 "Unexpected instruction for shrinking");

948

950 if (!InsElt || !InsElt->hasOneUse())

951 return nullptr;

952

955 Value *VecOp = InsElt->getOperand(0);

956 Value *ScalarOp = InsElt->getOperand(1);

957 Value *Index = InsElt->getOperand(2);

958

960

961

963 Value *NarrowOp = Builder.CreateCast(Opcode, ScalarOp, DestScalarTy);

965 }

966

967 return nullptr;

968}

969

972 return Result;

973

975 Type *DestTy = Trunc.getType(), *SrcTy = Src->getType();

977 unsigned SrcWidth = SrcTy->getScalarSizeInBits();

978

979

980

981

982

983 if ((DestTy->isVectorTy() || shouldChangeType(SrcTy, DestTy)) &&

984 TypeEvaluationHelper::canEvaluateTruncated(Src, DestTy, *this, &Trunc)) {

985

986

987

989 dbgs() << "ICE: EvaluateInDifferentType converting expression type"

990 " to avoid cast: "

991 << Trunc << '\n');

995 }

996

997

998

999

1000

1002 if (DestWidth * 2 < SrcWidth) {

1003 auto *NewDestTy = DestITy->getExtendedType();

1004 if (shouldChangeType(SrcTy, NewDestTy) &&

1005 TypeEvaluationHelper::canEvaluateTruncated(Src, NewDestTy, *this,

1006 &Trunc)) {

1008 dbgs() << "ICE: EvaluateInDifferentType converting expression type"

1009 " to reduce the width of operand of"

1010 << Trunc << '\n');

1012 return new TruncInst(Res, DestTy);

1013 }

1014 }

1015 }

1016

1017

1018

1020 return &Trunc;

1021

1022 if (DestWidth == 1) {

1024

1026 const APInt *C1;

1030

1034 }

1035

1037

1038

1040 }

1041

1044

1045 Constant *One = ConstantInt::get(SrcTy, APInt(SrcWidth, 1));

1049 }

1052

1053 Constant *One = ConstantInt::get(SrcTy, APInt(SrcWidth, 1));

1057 }

1058

1059 {

1062

1064 }

1065 }

1066

1071 }

1072 }

1073

1077 unsigned AWidth = A->getType()->getScalarSizeInBits();

1078 unsigned MaxShiftAmt = SrcWidth - std::max(DestWidth, AWidth);

1080 bool IsExact = OldSh->isExact();

1081

1082

1083

1085 APInt(SrcWidth, MaxShiftAmt)))) {

1086 auto GetNewShAmt = [&](unsigned Width) {

1087 Constant *MaxAmt = ConstantInt::get(SrcTy, Width - 1, false);

1092 DL);

1093 };

1094

1095

1096 if (A->getType() == DestTy) {

1097 Constant *ShAmt = GetNewShAmt(DestWidth);

1099 return IsExact ? BinaryOperator::CreateExactAShr(A, ShAmt)

1100 : BinaryOperator::CreateAShr(A, ShAmt);

1101 }

1102

1103

1104 if (Src->hasOneUse()) {

1105 Constant *ShAmt = GetNewShAmt(AWidth);

1106 Value *Shift = Builder.CreateAShr(A, ShAmt, "", IsExact);

1108 }

1109 }

1110

1111 }

1112

1114 return I;

1115

1117 return I;

1118

1120 return I;

1121

1122 if (Src->hasOneUse() &&

1123 (isa(SrcTy) || shouldChangeType(SrcTy, DestTy))) {

1124

1125

1128

1129

1130 APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth);

1132 Value *NewTrunc = Builder.CreateTrunc(A, DestTy, A->getName() + ".tr");

1135 }

1136 }

1137 }

1138

1140 return I;

1141

1143 return I;

1144

1145

1148 unsigned AWidth = A->getType()->getScalarSizeInBits();

1149 if (AWidth == DestWidth && AWidth > Log2_32(SrcWidth)) {

1150 Value *WidthDiff = ConstantInt::get(A->getType(), SrcWidth - AWidth);

1151 Value *NarrowCtlz =

1152 Builder.CreateIntrinsic(Intrinsic::ctlz, {Trunc.getType()}, {A, B});

1153 return BinaryOperator::CreateAdd(NarrowCtlz, WidthDiff);

1154 }

1155 }

1156

1162 if (std::optional MaxVScale = Attr.getVScaleRangeMax())

1163 if (Log2_32(*MaxVScale) < DestWidth)

1165 }

1166 }

1167

1168 if (DestWidth == 1 &&

1172

1178 }

1181 &Trunc)) {

1184 }

1185

1186 const APInt *C1;

1188

1189

1193 }

1194

1195

1196

1197

1201 }

1202

1203

1204

1205

1209 }

1210

1211 return Changed ? &Trunc : nullptr;

1212}

1213

1216

1217

1218

1219

1220

1221

1222

1223

1224

1225

1226 const APInt *Op1CV;

1227 if (match(Cmp->getOperand(1), m_APInt(Op1CV))) {

1228

1229

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

1232 Value *Sh = ConstantInt::get(In->getType(),

1233 In->getType()->getScalarSizeInBits() - 1);

1234 In = Builder.CreateLShr(In, Sh, In->getName() + ".lobit");

1235 if (In->getType() != Zext.getType())

1236 In = Builder.CreateIntCast(In, Zext.getType(), false );

1237

1239 }

1240

1241

1242

1243

1244

1245

1246 if (Op1CV->isZero() && Cmp->isEquality()) {

1247

1248

1250 APInt KnownZeroMask(~Known.Zero);

1251 uint32_t ShAmt = KnownZeroMask.logBase2();

1252 bool IsExpectShAmt = KnownZeroMask.isPowerOf2() &&

1254 if (IsExpectShAmt &&

1255 (Cmp->getOperand(0)->getType() == Zext.getType() ||

1257 Value *In = Cmp->getOperand(0);

1258 if (ShAmt) {

1259

1260

1261 In = Builder.CreateLShr(In, ConstantInt::get(In->getType(), ShAmt),

1262 In->getName() + ".lobit");

1263 }

1264

1265

1267 In = Builder.CreateXor(In, ConstantInt::get(In->getType(), 1));

1268

1269 if (Zext.getType() == In->getType())

1271

1274 }

1275 }

1276 }

1277

1278 if (Cmp->isEquality()) {

1279

1280

1281

1287 Value *Shift = And->getOperand(X == And->getOperand(0) ? 1 : 0);

1288 if (Zext.getType() == And->getType() ||

1294 Builder.CreateAnd(Lshr, ConstantInt::get(X->getType(), 1));

1296 Zext, Builder.CreateZExtOrTrunc(And1, Zext.getType()));

1297 }

1298 }

1299 }

1300

1301 return nullptr;

1302}

1303

1304

1305

1306

1307

1308

1309

1310

1311

1312

1313

1314

1315

1316

1317

1318

1319

1320

1321

1322bool TypeEvaluationHelper::canEvaluateZExtd(Value *V, Type *Ty,

1323 unsigned &BitsToClear,

1326 TypeEvaluationHelper TYH;

1327 return TYH.canEvaluateZExtdImpl(V, Ty, BitsToClear, IC, CxtI);

1328}

1329bool TypeEvaluationHelper::canEvaluateZExtdImpl(Value *V, Type *Ty,

1330 unsigned &BitsToClear,

1333 BitsToClear = 0;

1334 if (canAlwaysEvaluateInType(V, Ty))

1335 return true;

1336

1337

1338 if (canNotEvaluateInType(V, Ty))

1339 return false;

1340

1342 unsigned Tmp;

1343 switch (I->getOpcode()) {

1344 case Instruction::ZExt:

1345 case Instruction::SExt:

1346 case Instruction::Trunc:

1347 return true;

1348 case Instruction::And:

1349 case Instruction::Or:

1350 case Instruction::Xor:

1351 case Instruction::Add:

1352 case Instruction::Sub:

1353 case Instruction::Mul:

1354 if (!canEvaluateZExtdImpl(I->getOperand(0), Ty, BitsToClear, IC, CxtI) ||

1355 !canEvaluateZExtdImpl(I->getOperand(1), Ty, Tmp, IC, CxtI))

1356 return false;

1357

1358 if (BitsToClear == 0 && Tmp == 0)

1359 return true;

1360

1361

1362

1363 if (Tmp == 0 && I->isBitwiseLogicOp()) {

1364

1365

1366 unsigned VSize = V->getType()->getScalarSizeInBits();

1369 CxtI)) {

1370

1371

1372 if (I->getOpcode() == Instruction::And)

1373 BitsToClear = 0;

1374 return true;

1375 }

1376 }

1377

1378

1379 return false;

1380

1381 case Instruction::Shl: {

1382

1383

1384 uint64_t ShiftAmt;

1386 if (!canEvaluateZExtdImpl(I->getOperand(0), Ty, BitsToClear, IC, CxtI))

1387 return false;

1388 BitsToClear = ShiftAmt < BitsToClear ? BitsToClear - ShiftAmt : 0;

1389 return true;

1390 }

1391 return false;

1392 }

1393 case Instruction::LShr: {

1394

1395

1396 uint64_t ShiftAmt;

1398 if (!canEvaluateZExtdImpl(I->getOperand(0), Ty, BitsToClear, IC, CxtI))

1399 return false;

1400 BitsToClear += ShiftAmt;

1401 if (BitsToClear > V->getType()->getScalarSizeInBits())

1402 BitsToClear = V->getType()->getScalarSizeInBits();

1403 return true;

1404 }

1405

1406 return false;

1407 }

1408 case Instruction::Select:

1409 if (!canEvaluateZExtdImpl(I->getOperand(1), Ty, Tmp, IC, CxtI) ||

1410 !canEvaluateZExtdImpl(I->getOperand(2), Ty, BitsToClear, IC, CxtI) ||

1411

1412

1413 Tmp != BitsToClear)

1414 return false;

1415 return true;

1416

1417 case Instruction::PHI: {

1418

1419

1420

1422 if (!canEvaluateZExtdImpl(PN->getIncomingValue(0), Ty, BitsToClear, IC,

1423 CxtI))

1424 return false;

1426 if (!canEvaluateZExtdImpl(PN->getIncomingValue(i), Ty, Tmp, IC, CxtI) ||

1427

1428

1429 Tmp != BitsToClear)

1430 return false;

1431 return true;

1432 }

1433 case Instruction::Call:

1434

1435

1437 if (II->getIntrinsicID() == Intrinsic::vscale)

1438 return true;

1439 return false;

1440 default:

1441

1442 return false;

1443 }

1444}

1445

1447

1448

1451 return nullptr;

1452

1453

1455 return Result;

1456

1458 Type *SrcTy = Src->getType(), *DestTy = Zext.getType();

1459

1460

1461 if (SrcTy->isIntOrIntVectorTy(1) && Zext.hasNonNeg())

1463

1464

1465 unsigned BitsToClear;

1466 if (shouldChangeType(SrcTy, DestTy) &&

1467 TypeEvaluationHelper::canEvaluateZExtd(Src, DestTy, BitsToClear, *this,

1468 &Zext)) {

1470 "Can't clear more bits than in SrcTy");

1471

1472

1474 dbgs() << "ICE: EvaluateInDifferentType converting expression type"

1475 " to avoid zero extend: "

1476 << Zext << '\n');

1479

1480

1482 if (SrcOp->hasOneUse())

1484

1485 uint32_t SrcBitsKept = SrcTy->getScalarSizeInBits() - BitsToClear;

1487

1488

1489

1492 &Zext))

1494

1495

1498 return BinaryOperator::CreateAnd(Res, C);

1499 }

1500

1501

1502

1503

1505

1506

1507

1508

1509 Value *A = CSrc->getOperand(0);

1510 unsigned SrcSize = A->getType()->getScalarSizeInBits();

1511 unsigned MidSize = CSrc->getType()->getScalarSizeInBits();

1513

1514

1515

1516

1517 if (SrcSize < DstSize) {

1519 Constant *AndConst = ConstantInt::get(A->getType(), AndValue);

1522 }

1523

1524 if (SrcSize == DstSize) {

1526 return BinaryOperator::CreateAnd(A, ConstantInt::get(A->getType(),

1527 AndValue));

1528 }

1529 if (SrcSize > DstSize) {

1532 return BinaryOperator::CreateAnd(Trunc,

1533 ConstantInt::get(Trunc->getType(),

1534 AndValue));

1535 }

1536 }

1537

1539 return transformZExtICmp(Cmp, Zext);

1540

1541

1545 X->getType() == DestTy)

1546 return BinaryOperator::CreateAnd(X, Builder.CreateZExt(C, DestTy));

1547

1548

1552 X->getType() == DestTy) {

1554 return BinaryOperator::CreateXor(Builder.CreateAnd(X, ZC), ZC);

1555 }

1556

1557

1558

1559

1560

1561

1563 X->getType() == DestTy) {

1565 return BinaryOperator::CreateAnd(X, ZextC);

1566 }

1567

1573 if (std::optional MaxVScale = Attr.getVScaleRangeMax()) {

1574 unsigned TypeWidth = Src->getType()->getScalarSizeInBits();

1575 if (Log2_32(*MaxVScale) < TypeWidth)

1577 }

1578 }

1579 }

1580

1582

1584 SrcTy->getScalarSizeInBits() >

1588 return &Zext;

1589 }

1590

1593 return &Zext;

1594 }

1595 }

1596

1597 return nullptr;

1598}

1599

1600

1603 Value *Op0 = Cmp->getOperand(0), *Op1 = Cmp->getOperand(1);

1605

1606

1607 if (!Op1->getType()->isIntOrIntVectorTy())

1608 return nullptr;

1609

1611

1612 Value *Sh = ConstantInt::get(Op0->getType(),

1614 Value *In = Builder.CreateAShr(Op0, Sh, Op0->getName() + ".lobit");

1615 if (In->getType() != Sext.getType())

1616 In = Builder.CreateIntCast(In, Sext.getType(), true );

1617

1619 }

1620

1622

1623

1624

1625 if (Cmp->hasOneUse() &&

1626 Cmp->isEquality() && (Op1C->isZero() || Op1C->getValue().isPowerOf2())){

1628

1629 APInt KnownZeroMask(~Known.Zero);

1630 if (KnownZeroMask.isPowerOf2()) {

1631 Value *In = Cmp->getOperand(0);

1632

1633

1634 if (!Op1C->isZero() && Op1C->getValue() != KnownZeroMask) {

1639 }

1640

1642

1643

1644 unsigned ShiftAmt = KnownZeroMask.countr_zero();

1645

1646 if (ShiftAmt)

1648 ConstantInt::get(In->getType(), ShiftAmt));

1649

1650

1651

1654 "sext");

1655 } else {

1656

1657

1658 unsigned ShiftAmt = KnownZeroMask.countl_zero();

1659

1660 if (ShiftAmt)

1662 ConstantInt::get(In->getType(), ShiftAmt));

1663

1664

1665 In = Builder.CreateAShr(In, ConstantInt::get(In->getType(),

1666 KnownZeroMask.getBitWidth() - 1), "sext");

1667 }

1668

1669 if (Sext.getType() == In->getType())

1672 }

1673 }

1674 }

1675

1676 return nullptr;

1677}

1678

1679

1680

1681

1682

1683

1684

1685

1686bool TypeEvaluationHelper::canEvaluateSExtd(Value *V, Type *Ty) {

1687 TypeEvaluationHelper TYH;

1688 return TYH.canEvaluateSExtdImpl(V, Ty) && TYH.allPendingVisited();

1689}

1690

1691bool TypeEvaluationHelper::canEvaluateSExtdImpl(Value *V, Type *Ty) {

1692 return canEvaluate(V, Ty, [this](Value *V, Type *Ty) {

1693 return canEvaluateSExtdPred(V, Ty);

1694 });

1695}

1696

1697bool TypeEvaluationHelper::canEvaluateSExtdPred(Value *V, Type *Ty) {

1699 "Can't sign extend type to a smaller type");

1700

1702 switch (I->getOpcode()) {

1703 case Instruction::SExt:

1704 case Instruction::ZExt:

1705 case Instruction::Trunc:

1706 return true;

1707 case Instruction::And:

1708 case Instruction::Or:

1709 case Instruction::Xor:

1710 case Instruction::Add:

1711 case Instruction::Sub:

1712 case Instruction::Mul:

1713

1714 return canEvaluateSExtdImpl(I->getOperand(0), Ty) &&

1715 canEvaluateSExtdImpl(I->getOperand(1), Ty);

1716

1717

1718

1719

1720 case Instruction::Select:

1721 return canEvaluateSExtdImpl(I->getOperand(1), Ty) &&

1722 canEvaluateSExtdImpl(I->getOperand(2), Ty);

1723

1724 case Instruction::PHI: {

1725

1726

1727

1730 if (!canEvaluateSExtdImpl(IncValue, Ty))

1731 return false;

1732 return true;

1733 }

1734 default:

1735

1736 break;

1737 }

1738

1739 return false;

1740}

1741

1743

1744

1746 return nullptr;

1747

1749 return I;

1750

1752 Type *SrcTy = Src->getType(), *DestTy = Sext.getType();

1755

1756

1759 CI->setNonNeg(true);

1760 return CI;

1761 }

1762

1763

1764 bool ShouldExtendExpression = true;

1765 Value *TruncSrc = nullptr;

1766

1767

1770 ShouldExtendExpression = false;

1771 if (ShouldExtendExpression && shouldChangeType(SrcTy, DestTy) &&

1772 TypeEvaluationHelper::canEvaluateSExtd(Src, DestTy)) {

1773

1775 dbgs() << "ICE: EvaluateInDifferentType converting expression type"

1776 " to avoid sign extend: "

1777 << Sext << '\n');

1780

1781

1782

1785

1786

1787 Value *ShAmt = ConstantInt::get(DestTy, DestBitSize - SrcBitSize);

1788 return BinaryOperator::CreateAShr(Builder.CreateShl(Res, ShAmt, "sext"),

1789 ShAmt);

1790 }

1791

1792 Value *X = TruncSrc;

1793 if (X) {

1794

1795

1796 unsigned XBitSize = X->getType()->getScalarSizeInBits();

1801 ResTrunc->setHasNoSignedWrap(true);

1802 return Res;

1803 }

1804

1805

1806 if (Src->hasOneUse() && X->getType() == DestTy) {

1807

1808 Constant *ShAmt = ConstantInt::get(DestTy, DestBitSize - SrcBitSize);

1809 return BinaryOperator::CreateAShr(Builder.CreateShl(X, ShAmt), ShAmt);

1810 }

1811

1812

1813

1814

1815

1817 if (Src->hasOneUse() &&

1820 Value *Ashr = Builder.CreateAShr(Y, XBitSize - SrcBitSize);

1822 }

1823 }

1824

1826 return transformSExtICmp(Cmp, Sext);

1827

1828

1829

1830

1831

1832

1833

1834

1835

1836

1837

1838

1839

1840

1842

1843 Constant *BA = nullptr, *CA = nullptr;

1849 assert(WideCurrShAmt && "Constant folding of ImmConstant cannot fail");

1854 NumLowbitsLeft);

1855 NewShAmt =

1858 return BinaryOperator::CreateAShr(A, NewShAmt);

1859 }

1860

1861

1862

1863

1866 Type *XTy = X->getType();

1868 Constant *ShlAmtC = ConstantInt::get(XTy, XBitSize - SrcBitSize);

1869 Constant *AshrAmtC = ConstantInt::get(XTy, XBitSize - 1);

1870 if (XTy == DestTy)

1871 return BinaryOperator::CreateAShr(Builder.CreateShl(X, ShlAmtC),

1872 AshrAmtC);

1876 }

1877 }

1878

1884 if (std::optional MaxVScale = Attr.getVScaleRangeMax())

1885 if (Log2_32(*MaxVScale) < (SrcBitSize - 1))

1887 }

1888 }

1889

1890 return nullptr;

1891}

1892

1893

1894

1896 bool losesInfo;

1898 return !losesInfo;

1899}

1900

1902 bool PreferBFloat) {

1903

1906

1909

1913 return nullptr;

1914

1917

1918 return nullptr;

1919}

1920

1923 if (Ty->getScalarType()->isPPC_FP128Ty())

1924 return nullptr;

1925

1926 Type *ShrinkTy =

1928 if (ShrinkTy)

1931

1932 return ShrinkTy;

1933}

1934

1935

1936

1940 if (!CV || !CVVTy)

1941 return nullptr;

1942

1943 Type *MinType = nullptr;

1944

1945 unsigned NumElts = CVVTy->getNumElements();

1946

1947

1948

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

1951 continue;

1952

1954 if (!CFP)

1955 return nullptr;

1956

1958 if (T)

1959 return nullptr;

1960

1961

1962

1963 if (!MinType || T->getFPMantissaWidth() > MinType->getFPMantissaWidth())

1964 MinType = T;

1965 }

1966

1967

1969}

1970

1971

1974 return FPExt->getOperand(0)->getType();

1975

1976

1977

1978

1981 return T;

1982

1983

1989

1990

1991

1993 return T;

1994

1995 return V->getType();

1996}

1997

1998

1999

2002 assert((Opcode == CastInst::SIToFP || Opcode == CastInst::UIToFP) &&

2003 "Unexpected cast");

2004 Value *Src = I.getOperand(0);

2005 Type *SrcTy = Src->getType();

2006 Type *FPTy = I.getType();

2007 bool IsSigned = Opcode == Instruction::SIToFP;

2008 int SrcSize = (int)SrcTy->getScalarSizeInBits() - IsSigned;

2009

2010

2011

2013 if (SrcSize <= DestNumSigBits)

2014 return true;

2015

2016

2017

2020

2021

2022 int SrcNumSigBits = F->getType()->getFPMantissaWidth();

2024 SrcNumSigBits++;

2025

2026

2027

2028

2029 if (SrcNumSigBits > 0 && DestNumSigBits > 0 &&

2030 SrcNumSigBits <= DestNumSigBits)

2031 return true;

2032 }

2033

2034

2035

2036

2038 int SigBits = (int)SrcTy->getScalarSizeInBits() -

2041 if (SigBits <= DestNumSigBits)

2042 return true;

2043

2044 return false;

2045}

2046

2049 return I;

2050

2051

2052

2053

2054

2055

2056

2057

2060 if (BO && BO->hasOneUse()) {

2061 bool PreferBFloat = Ty->getScalarType()->isBFloatTy();

2064 unsigned OpWidth = BO->getType()->getFPMantissaWidth();

2067 unsigned SrcWidth = std::max(LHSWidth, RHSWidth);

2068 unsigned DstWidth = Ty->getFPMantissaWidth();

2069 switch (BO->getOpcode()) {

2070 default: break;

2071 case Instruction::FAdd:

2072 case Instruction::FSub:

2073

2074

2075

2076

2077

2078

2079

2080

2081

2082

2083

2084

2085

2086

2087

2088

2089

2090

2091 if (OpWidth >= 2*DstWidth+1 && DstWidth >= SrcWidth) {

2092 Value *LHS = Builder.CreateFPTrunc(BO->getOperand(0), Ty);

2093 Value *RHS = Builder.CreateFPTrunc(BO->getOperand(1), Ty);

2096 return RI;

2097 }

2098 break;

2099 case Instruction::FMul:

2100

2101

2102

2103

2104

2105 if (OpWidth >= LHSWidth + RHSWidth && DstWidth >= SrcWidth) {

2106 Value *LHS = Builder.CreateFPTrunc(BO->getOperand(0), Ty);

2107 Value *RHS = Builder.CreateFPTrunc(BO->getOperand(1), Ty);

2109 }

2110 break;

2111 case Instruction::FDiv:

2112

2113

2114

2115

2116

2117

2118 if (OpWidth >= 2*DstWidth && DstWidth >= SrcWidth) {

2119 Value *LHS = Builder.CreateFPTrunc(BO->getOperand(0), Ty);

2120 Value *RHS = Builder.CreateFPTrunc(BO->getOperand(1), Ty);

2122 }

2123 break;

2124 case Instruction::FRem: {

2125

2126

2127

2128

2129 if (SrcWidth == OpWidth)

2130 break;

2131 Value *LHS, *RHS;

2132 if (LHSWidth == SrcWidth) {

2133 LHS = Builder.CreateFPTrunc(BO->getOperand(0), LHSMinType);

2134 RHS = Builder.CreateFPTrunc(BO->getOperand(1), LHSMinType);

2135 } else {

2136 LHS = Builder.CreateFPTrunc(BO->getOperand(0), RHSMinType);

2137 RHS = Builder.CreateFPTrunc(BO->getOperand(1), RHSMinType);

2138 }

2139

2140 Value *ExactResult = Builder.CreateFRemFMF(LHS, RHS, BO);

2142 }

2143 }

2144 }

2145

2146

2149 if (Op && Op->hasOneUse()) {

2152 FMF &= FPMO->getFastMathFlags();

2153

2155 Value *InnerTrunc = Builder.CreateFPTruncFMF(X, Ty, FMF);

2156 Value *Neg = Builder.CreateFNegFMF(InnerTrunc, FMF);

2158 }

2159

2160

2161

2164 X->getType() == Ty) {

2165

2166 Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);

2168 Builder.CreateSelectFMF(Cond, X, NarrowY, FMF, "narrow.sel", Op);

2170 }

2172 X->getType() == Ty) {

2173

2174 Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);

2176 Builder.CreateSelectFMF(Cond, NarrowY, X, FMF, "narrow.sel", Op);

2178 }

2179 }

2180

2182 switch (II->getIntrinsicID()) {

2183 default: break;

2184 case Intrinsic::ceil:

2185 case Intrinsic::fabs:

2186 case Intrinsic:🤣

2187 case Intrinsic::nearbyint:

2188 case Intrinsic::rint:

2189 case Intrinsic::round:

2190 case Intrinsic::roundeven:

2191 case Intrinsic::trunc: {

2192 Value *Src = II->getArgOperand(0);

2193 if (!Src->hasOneUse())

2194 break;

2195

2196

2197

2198

2199 if (II->getIntrinsicID() != Intrinsic::fabs) {

2201 if (!FPExtSrc || FPExtSrc->getSrcTy() != Ty)

2202 break;

2203 }

2204

2205

2206

2207 Value *InnerTrunc = Builder.CreateFPTrunc(Src, Ty);

2209 FPT.getModule(), II->getIntrinsicID(), Ty);

2211 II->getOperandBundlesAsDefs(OpBundles);

2214

2215

2217 return NewCI;

2218 }

2219 }

2220 }

2221

2223 return I;

2224

2229 return CastInst::Create(FPCast->getOpcode(), FPCast->getOperand(0), Ty);

2230 }

2231

2232 return nullptr;

2233}

2234

2236

2237

2243 return CastInst::Create(FPCast->getOpcode(), FPCast->getOperand(0), Ty);

2244 }

2245

2247}

2248

2249

2250

2251

2252

2255 return nullptr;

2256

2258 Value *X = OpI->getOperand(0);

2259 Type *XType = X->getType();

2262

2263

2264

2265

2266

2267

2268

2270

2271

2272

2273

2274

2276 if (OutputSize > OpI->getType()->getFPMantissaWidth())

2277 return nullptr;

2278 }

2279

2282 if (IsInputSigned && IsOutputSigned)

2283 return new SExtInst(X, DestType);

2284 return new ZExtInst(X, DestType);

2285 }

2288

2289 assert(XType == DestType && "Unexpected types for int to FP to int casts");

2291}

2292

2294

2301

2302 return nullptr;

2303}

2304

2307 return I;

2308

2310 return I;

2311

2313}

2314

2317 return I;

2318

2320 return I;

2321

2323}

2324

2327 return R;

2330 return &CI;

2331 }

2332 return nullptr;

2333}

2334

2337 return R;

2339 auto *UI =

2341 UI->setNonNeg(true);

2342 return UI;

2343 }

2344 return nullptr;

2345}

2346

2348

2349

2350

2353 DL.getPointerSizeInBits(AS)) {

2358 }

2359

2360

2361

2362

2365 auto UsesPointerAsInt = [](User *U) {

2367 return true;

2370 return false;

2371 };

2376 Base->getType()->getPointerAddressSpace() &&

2379 }

2380

2382 return I;

2383

2384 return nullptr;

2385}

2386

2388

2391 while (true) {

2393 if (GEP || GEP->hasOneUse())

2394 break;

2396 Ptr = GEP->getPointerOperand();

2397 }

2398

2399

2400 if (GEPs.empty() || PtrTy != Ptr->getType())

2401 return nullptr;

2402

2403

2405 Type *IdxTy = DL.getIndexType(PtrTy);

2407 Res->getType() == IntTy && IntTy == IdxTy) {

2408

2411 } else {

2412 return nullptr;

2413 }

2414

2415

2418 Res = Builder.CreateAdd(Res, Offset, "", GEP->hasNoUnsignedWrap());

2419 }

2420 return Builder.CreateZExtOrTrunc(Res, IntTy);

2421}

2422

2424

2425

2426

2431 unsigned TySize = Ty->getScalarSizeInBits();

2432 unsigned PtrSize = DL.getPointerSizeInBits(AS);

2433 if (TySize != PtrSize) {

2434 Type *IntPtrTy =

2438 }

2439

2440

2441

2442

2443 Value *Ptr, *Mask;

2446 Mask->getType() == Ty)

2447 return BinaryOperator::CreateAnd(Builder.CreatePtrToInt(Ptr, Ty), Mask);

2448

2451

2452 Value *Vec, *Scalar, *Index;

2457

2458

2459 Value *NewCast = Builder.CreatePtrToInt(Scalar, Ty->getScalarType());

2461 }

2462

2464}

2465

2469

2470

2471

2472

2473 Value *Ptr, *Mask;

2476 Mask->getType() == Ty)

2477 return BinaryOperator::CreateAnd(Builder.CreatePtrToAddr(Ptr), Mask);

2478

2481

2482

2484}

2485

2486

2487

2488

2489

2490

2491

2492

2493

2494

2495

2496

2497

2498

2499

2500

2501

2505

2506

2507

2509

2510 if (SrcTy->getElementType() != DestTy->getElementType()) {

2511

2512

2513

2514

2515 if (SrcTy->getElementType()->getPrimitiveSizeInBits() !=

2516 DestTy->getElementType()->getPrimitiveSizeInBits())

2517 return nullptr;

2518

2519 SrcTy =

2523 }

2524

2528

2529 assert(SrcElts != DestElts && "Element counts should be different.");

2530

2531

2532

2533

2537

2538 if (SrcElts > DestElts) {

2539

2540

2541

2542

2544

2545

2546

2547 ShuffleMask = ShuffleMaskStorage;

2548 if (IsBigEndian)

2549 ShuffleMask = ShuffleMask.take_back(DestElts);

2550 else

2551 ShuffleMask = ShuffleMask.take_front(DestElts);

2552 } else {

2553

2554

2555

2557

2559

2560

2561

2562 unsigned DeltaElts = DestElts - SrcElts;

2563 if (IsBigEndian)

2564 ShuffleMaskStorage.insert(ShuffleMaskStorage.begin(), DeltaElts, NullElt);

2565 else

2566 ShuffleMaskStorage.append(DeltaElts, NullElt);

2567 ShuffleMask = ShuffleMaskStorage;

2568 }

2569

2571}

2572

2574 return Value % Ty->getPrimitiveSizeInBits() == 0;

2575}

2576

2578 return Value / Ty->getPrimitiveSizeInBits();

2579}

2580

2581

2582

2583

2584

2585

2586

2587

2588

2589

2590

2595 "Shift should be a multiple of the element type size");

2596

2597

2599

2600

2601

2602 if (V->getType() == VecEltTy) {

2603

2605 if (C->isNullValue())

2606 return true;

2607

2610 ElementIndex = Elements.size() - ElementIndex - 1;

2611

2612

2613 if (Elements[ElementIndex])

2614 return false;

2615

2616 Elements[ElementIndex] = V;

2617 return true;

2618 }

2619

2621

2622

2623 unsigned NumElts = getTypeSizeIndex(C->getType()->getPrimitiveSizeInBits(),

2624 VecEltTy);

2625

2626

2627 if (NumElts == 1)

2629 Shift, Elements, VecEltTy, isBigEndian);

2630

2631

2632

2635 C->getType()->getPrimitiveSizeInBits()));

2638

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

2640 unsigned ShiftI = i * ElementSize;

2642 Instruction::LShr, C, ConstantInt::get(C->getType(), ShiftI));

2643 if (!Piece)

2644 return false;

2645

2649 return false;

2650 }

2651 return true;

2652 }

2653

2654 if (!V->hasOneUse()) return false;

2655

2657 if (I) return false;

2658 switch (I->getOpcode()) {

2659 default: return false;

2660 case Instruction::BitCast:

2661 if (I->getOperand(0)->getType()->isVectorTy())

2662 return false;

2665 case Instruction::ZExt:

2667 I->getOperand(0)->getType()->getPrimitiveSizeInBits(),

2668 VecEltTy))

2669 return false;

2672 case Instruction::Or:

2677 case Instruction::Shl: {

2678

2680 if (!CI) return false;

2685 }

2686

2687 }

2688}

2689

2690

2691

2692

2693

2694

2695

2696

2697

2698

2699

2700

2701

2702

2703

2704

2709

2710

2711

2713 return nullptr;

2714

2717 DestVecTy->getElementType(),

2719 return nullptr;

2720

2721

2722

2723

2725 for (unsigned i = 0, e = Elements.size(); i != e; ++i) {

2726 if (!Elements[i]) continue;

2727

2730 }

2731

2732 return Result;

2733}

2734

2735

2736

2737

2738

2741 Value *VecOp, *Index;

2744 return nullptr;

2745

2746

2747

2754 }

2755

2756

2757

2759 if (DestType->isVectorTy() && FixedVType && FixedVType->getNumElements() == 1)

2760 return CastInst::Create(Instruction::BitCast, VecOp, DestType);

2761

2762 return nullptr;

2763}

2764

2765

2770

2773 return nullptr;

2774

2775

2776

2777

2779 return nullptr;

2780

2783

2786 if (X->getType()->isFPOrFPVectorTy() &&

2787 Y->getType()->isIntOrIntVectorTy()) {

2788 Value *CastedOp =

2789 Builder.CreateBitCast(BO->getOperand(0), Y->getType());

2790 Value *NewBO = Builder.CreateBinOp(BO->getOpcode(), CastedOp, Y);

2792 }

2793 if (X->getType()->isIntOrIntVectorTy() &&

2794 Y->getType()->isFPOrFPVectorTy()) {

2795 Value *CastedOp =

2796 Builder.CreateBitCast(BO->getOperand(1), X->getType());

2797 Value *NewBO = Builder.CreateBinOp(BO->getOpcode(), CastedOp, X);

2799 }

2800 }

2801 return nullptr;

2802 }

2803

2805 return nullptr;

2806

2810

2811 Value *CastedOp1 = Builder.CreateBitCast(BO->getOperand(1), DestTy);

2813 }

2814

2817

2818 Value *CastedOp0 = Builder.CreateBitCast(BO->getOperand(0), DestTy);

2820 }

2821

2822

2823

2824

2825

2828

2829 Value *CastedOp0 = Builder.CreateBitCast(BO->getOperand(0), DestTy);

2830 Value *CastedC = Builder.CreateBitCast(C, DestTy);

2832 }

2833

2834 return nullptr;

2835}

2836

2837

2843 return nullptr;

2844

2845

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

2850 CondVTy->getElementCount() !=

2852 return nullptr;

2853

2854

2855

2856

2857

2859 return nullptr;

2860

2865

2866 Value *CastedVal = Builder.CreateBitCast(FVal, DestTy);

2868 }

2869

2872

2873 Value *CastedVal = Builder.CreateBitCast(TVal, DestTy);

2875 }

2876

2877 return nullptr;

2878}

2879

2880

2884 return false;

2885 }

2886 return true;

2887}

2888

2889

2890

2891

2892

2893

2894

2895

2896

2899

2901 return nullptr;

2902

2904 Type *SrcTy = Src->getType();

2906

2908 SmallSetVector<PHINode *, 4> OldPhiNodes;

2909

2910

2911

2912

2913

2915 OldPhiNodes.insert(PN);

2916 while (!PhiWorklist.empty()) {

2918 for (Value *IncValue : OldPN->incoming_values()) {

2920 continue;

2921

2923

2924

2925

2926

2927 Value *Addr = LI->getOperand(0);

2929 return nullptr;

2930

2931

2932

2933

2935 return nullptr;

2936 if (LI->hasOneUse() && LI->isSimple())

2937 continue;

2938

2939

2940 return nullptr;

2941 }

2942

2944 if (OldPhiNodes.insert(PNode))

2946 continue;

2947 }

2948

2950

2951 if (!BCI)

2952 return nullptr;

2953

2954

2955 Type *TyA = BCI->getOperand(0)->getType();

2956 Type *TyB = BCI->getType();

2957 if (TyA != DestTy || TyB != SrcTy)

2958 return nullptr;

2959 }

2960 }

2961

2962

2963

2964 for (auto *OldPN : OldPhiNodes) {

2965 for (User *V : OldPN->users()) {

2967 if (SI->isSimple() || SI->getOperand(0) != OldPN)

2968 return nullptr;

2970

2971 Type *TyB = BCI->getOperand(0)->getType();

2972 Type *TyA = BCI->getType();

2973 if (TyA != DestTy || TyB != SrcTy)

2974 return nullptr;

2976

2977

2978

2979 if (!OldPhiNodes.contains(PHI))

2980 return nullptr;

2981 } else {

2982 return nullptr;

2983 }

2984 }

2985 }

2986

2987

2988 SmallDenseMap<PHINode *, PHINode *> NewPNodes;

2989 for (auto *OldPN : OldPhiNodes) {

2990 Builder.SetInsertPoint(OldPN);

2991 PHINode *NewPN = Builder.CreatePHI(DestTy, OldPN->getNumOperands());

2992 NewPNodes[OldPN] = NewPN;

2993 }

2994

2995

2996 for (auto *OldPN : OldPhiNodes) {

2997 PHINode *NewPN = NewPNodes[OldPN];

2998 for (unsigned j = 0, e = OldPN->getNumOperands(); j != e; ++j) {

2999 Value *V = OldPN->getOperand(j);

3000 Value *NewV = nullptr;

3004

3005

3006 Builder.SetInsertPoint(LI);

3008

3009

3013 NewV = BCI->getOperand(0);

3015 NewV = NewPNodes[PrevPN];

3016 }

3018 NewPN->addIncoming(NewV, OldPN->getIncomingBlock(j));

3019 }

3020 }

3021

3022

3023

3024

3025

3026

3027

3028

3029

3030

3032 for (auto *OldPN : OldPhiNodes) {

3033 PHINode *NewPN = NewPNodes[OldPN];

3036 assert(SI->isSimple() && SI->getOperand(0) == OldPN);

3037 Builder.SetInsertPoint(SI);

3038 auto *NewBC =

3040 SI->setOperand(0, NewBC);

3043 }

3045 Type *TyB = BCI->getOperand(0)->getType();

3046 Type *TyA = BCI->getType();

3047 assert(TyA == DestTy && TyB == SrcTy);

3048 (void) TyA;

3049 (void) TyB;

3051 if (BCI == &CI)

3052 RetVal = I;

3054 assert(OldPhiNodes.contains(PHI));

3055 (void) PHI;

3056 } else {

3058 }

3059 }

3060 }

3061

3062 return RetVal;

3063}

3064

3065

3066

3073 return nullptr;

3077 return nullptr;

3078 if (X->getType() != FTy)

3079 return nullptr;

3081 return nullptr;

3082

3083 return Builder.CreateCopySign(Builder.CreateBitCast(Y, FTy), X);

3084}

3085

3087

3088

3090 Type *SrcTy = Src->getType();

3092

3093

3094

3095 if (DestTy == Src->getType())

3097

3100

3101

3102

3109 return I;

3110 }

3111

3112

3113

3114

3117 }

3118 }

3119

3121 if (SrcVTy->getNumElements() == 1) {

3122

3123

3126 Builder.CreateExtractElement(Src,

3128 return CastInst::Create(Instruction::BitCast, Elem, DestTy);

3129 }

3130

3131

3132

3133

3135 return new BitCastInst(InsElt->getOperand(1), DestTy);

3136 }

3137

3138

3144 DestTy->isIntegerTy() && X->getType() == DestTy &&

3145 Y->getType()->isIntegerTy() && isDesirableIntType(BitWidth)) {

3146

3147 if (DL.isBigEndian())

3148 IndexC = SrcVTy->getNumElements() - 1 - IndexC;

3149

3150

3151

3152 if (IndexC == 0) {

3153

3154 unsigned EltWidth = Y->getType()->getScalarSizeInBits();

3158 return BinaryOperator::CreateOr(AndX, ZextY);

3159 }

3160 }

3161 }

3162

3164

3165

3166 Value *ShufOp0 = Shuf->getOperand(0);

3167 Value *ShufOp1 = Shuf->getOperand(1);

3168 auto ShufElts = cast(Shuf->getType())->getElementCount();

3170 if (Shuf->hasOneUse() && DestTy->isVectorTy() &&

3172 ShufElts == SrcVecElts) {

3174

3175

3176

3181 Value *LHS = Builder.CreateBitCast(ShufOp0, DestTy);

3182 Value *RHS = Builder.CreateBitCast(ShufOp1, DestTy);

3183

3184

3186 }

3187 }

3188

3189

3190

3191

3192

3193 if (DestTy->isIntegerTy() && ShufElts.getKnownMinValue() % 2 == 0 &&

3194 Shuf->hasOneUse() && Shuf->isReverse()) {

3195 unsigned IntrinsicNum = 0;

3197 SrcTy->getScalarSizeInBits() == 8) {

3198 IntrinsicNum = Intrinsic::bswap;

3199 } else if (SrcTy->getScalarSizeInBits() == 1) {

3200 IntrinsicNum = Intrinsic::bitreverse;

3201 }

3202 if (IntrinsicNum != 0) {

3203 assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask");

3206 CI.getModule(), IntrinsicNum, DestTy);

3207 Value *ScalarX = Builder.CreateBitCast(ShufOp0, DestTy);

3209 }

3210 }

3211 }

3212

3213

3215 if (Instruction *I = optimizeBitCastFromPhi(CI, PN))

3216 return I;

3217

3219 return I;

3220

3222 return I;

3223

3225 return I;

3226

3229

3231}

3232

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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static std::optional< bool > isBigEndian(const SmallDenseMap< int64_t, int64_t, 8 > &MemOffset2Idx, int64_t LowestIdx)

Given a map from byte offsets in memory to indices in a load/store, determine if that map corresponds...

This file defines the DenseMap class.

static bool isSigned(unsigned int Opcode)

static bool collectInsertionElements(Value *V, unsigned Shift, SmallVectorImpl< Value * > &Elements, Type *VecEltTy, bool isBigEndian)

V is a value which is inserted into a vector of VecEltTy.

Definition InstCombineCasts.cpp:2591

static bool hasStoreUsersOnly(CastInst &CI)

Check if all users of CI are StoreInsts.

Definition InstCombineCasts.cpp:2881

static Value * foldCopySignIdioms(BitCastInst &CI, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)

Fold (bitcast (or (and (bitcast X to int), signmask), nneg Y) to fp) to copysign((bitcast Y to fp),...

Definition InstCombineCasts.cpp:3067

static Type * shrinkFPConstantVector(Value *V, bool PreferBFloat)

Definition InstCombineCasts.cpp:1937

static Instruction * canonicalizeBitCastExtElt(BitCastInst &BitCast, InstCombinerImpl &IC)

Canonicalize scalar bitcasts of extracted elements into a bitcast of the vector followed by extract e...

Definition InstCombineCasts.cpp:2739

static Instruction * shrinkSplatShuffle(TruncInst &Trunc, InstCombiner::BuilderTy &Builder)

Try to narrow the width of a splat shuffle.

Definition InstCombineCasts.cpp:919

static Instruction * foldFPtoI(Instruction &FI, InstCombiner &IC)

Definition InstCombineCasts.cpp:2293

static Instruction * foldBitCastSelect(BitCastInst &BitCast, InstCombiner::BuilderTy &Builder)

Change the type of a select if we can eliminate a bitcast.

Definition InstCombineCasts.cpp:2838

static Instruction * foldBitCastBitwiseLogic(BitCastInst &BitCast, InstCombiner::BuilderTy &Builder)

Change the type of a bitwise logic operation if we can eliminate a bitcast.

Definition InstCombineCasts.cpp:2766

static bool fitsInFPType(APFloat F, const fltSemantics &Sem)

Return a Constant* for the specified floating-point constant if it fits in the specified FP type with...

Definition InstCombineCasts.cpp:1895

static Instruction * optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy, InstCombinerImpl &IC)

This input value (which is known to have vector type) is being zero extended or truncated to the spec...

Definition InstCombineCasts.cpp:2503

static Instruction * shrinkInsertElt(CastInst &Trunc, InstCombiner::BuilderTy &Builder)

Try to narrow the width of an insert element.

Definition InstCombineCasts.cpp:943

static Type * getMinimumFPType(Value *V, bool PreferBFloat)

Find the minimum FP type we can safely truncate to.

Definition InstCombineCasts.cpp:1972

SmallDenseMap< Value *, Value *, 8 > EvaluatedMap

Definition InstCombineCasts.cpp:37

static bool isMultipleOfTypeSize(unsigned Value, Type *Ty)

Definition InstCombineCasts.cpp:2573

static Value * optimizeIntegerToVectorInsertions(BitCastInst &CI, InstCombinerImpl &IC)

If the input is an 'or' instruction, we may be doing shifts and ors to assemble the elements of the v...

Definition InstCombineCasts.cpp:2705

static Type * shrinkFPConstant(LLVMContext &Ctx, const APFloat &F, bool PreferBFloat)

Definition InstCombineCasts.cpp:1901

static Instruction * foldVecExtTruncToExtElt(TruncInst &Trunc, InstCombinerImpl &IC)

Whenever an element is extracted from a vector, optionally shifted down, and then truncated,...

Definition InstCombineCasts.cpp:674

static Value * EvaluateInDifferentTypeImpl(Value *V, Type *Ty, bool isSigned, InstCombinerImpl &IC, EvaluatedMap &Processed)

Definition InstCombineCasts.cpp:39

static bool isKnownExactCastIntToFP(CastInst &I, InstCombinerImpl &IC)

Return true if the cast from integer to FP can be proven to be exact for all possible inputs (the con...

Definition InstCombineCasts.cpp:2000

static unsigned getTypeSizeIndex(unsigned Value, Type *Ty)

Definition InstCombineCasts.cpp:2577

static Instruction * foldVecTruncToExtElt(TruncInst &Trunc, InstCombinerImpl &IC)

Given a vector that is bitcast to an integer, optionally logically right-shifted, and truncated,...

Definition InstCombineCasts.cpp:624

This file provides internal interfaces used to implement the InstCombine.

This file provides the interface for the instcombine pass implementation.

uint64_t IntrinsicInst * II

const SmallVectorImpl< MachineOperand > & Cond

This file implements a set that has insertion order iteration characteristics.

This file defines the SmallVector class.

static unsigned getScalarSizeInBits(Type *Ty)

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

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

static SymbolRef::Type getType(const Symbol *Sym)

static const fltSemantics & IEEEsingle()

static const fltSemantics & BFloat()

static const fltSemantics & IEEEdouble()

static constexpr roundingMode rmNearestTiesToEven

static const fltSemantics & IEEEhalf()

static LLVM_ABI unsigned int semanticsIntSizeInBits(const fltSemantics &, bool)

Class for arbitrary precision integers.

LLVM_ABI APInt udiv(const APInt &RHS) const

Unsigned division operation.

uint64_t getZExtValue() const

Get zero extended value.

bool isZero() const

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

LLVM_ABI APInt urem(const APInt &RHS) const

Unsigned remainder operation.

bool ult(const APInt &RHS) const

Unsigned less than comparison.

int32_t exactLogBase2() const

unsigned countr_zero() const

Count the number of trailing zero bits.

static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)

Constructs an APInt value that has the bottom loBitsSet bits set.

static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)

Constructs an APInt value that has the top hiBitsSet bits set.

static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)

Constructs an APInt value that has a contiguous range of bits set.

unsigned countr_one() const

Count the number of trailing one bits.

bool uge(const APInt &RHS) const

Unsigned greater or equal comparison.

This class represents a conversion between pointers from one address space to another.

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

Functions, function parameters, and return types can have attributes to indicate how they should be t...

LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const

Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.

BinaryOps getOpcode() const

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

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

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

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

This is the base class for all instructions that perform data casts.

Type * getSrcTy() const

Return the source type, as a convenience.

Instruction::CastOps getOpcode() const

Return the opcode of this CastInst.

static LLVM_ABI unsigned isEliminableCastPair(Instruction::CastOps firstOpcode, Instruction::CastOps secondOpcode, Type *SrcTy, Type *MidTy, Type *DstTy, const DataLayout *DL)

Determine how a pair of casts can be eliminated, if they can be at all.

static LLVM_ABI CastInst * CreateIntegerCast(Value *S, Type *Ty, bool isSigned, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Create a ZExt, BitCast, or Trunc for int -> int casts.

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

Create an FPExt, BitCast, or FPTrunc for fp -> fp casts.

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

Create a Trunc or BitCast cast instruction.

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

Create a BitCast, a PtrToInt, or an IntToPTr 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 ...

Type * getDestTy() const

Return the destination type, as a convenience.

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ ICMP_SLT

signed less than

@ ICMP_UGE

unsigned greater or equal

@ ICMP_ULT

unsigned less than

@ ICMP_ULE

unsigned less or equal

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

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

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

ConstantFP - Floating Point Values [float, double].

const APFloat & getValueAPF() const

This is the shared class of boolean and integer constants.

static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)

uint64_t getZExtValue() const

Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...

This is an important base class in LLVM.

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

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

static LLVM_ABI Constant * getAllOnesValue(Type *Ty)

static LLVM_ABI Constant * getNullValue(Type *Ty)

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

LLVM_ABI bool isElementWiseEqual(Value *Y) const

Return true if this constant and a constant 'Y' are element-wise equal.

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

This class represents an extension of floating point types.

This class represents a cast from floating point to signed integer.

This class represents a cast from floating point to unsigned integer.

This class represents a truncation of floating point types.

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

Class to represent fixed width SIMD vectors.

static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)

FunctionType * getFunctionType() const

Returns the FunctionType for me.

Attribute getFnAttribute(Attribute::AttrKind Kind) const

Return the attribute for the given attribute kind.

bool hasFnAttribute(Attribute::AttrKind Kind) const

Return true if the function has the attribute.

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

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

Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")

ConstantInt * getInt32(uint32_t C)

Get a constant 32-bit value.

Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")

static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

Instruction * visitZExt(ZExtInst &Zext)

Definition InstCombineCasts.cpp:1446

Instruction * visitAddrSpaceCast(AddrSpaceCastInst &CI)

Definition InstCombineCasts.cpp:3233

Instruction * visitSExt(SExtInst &Sext)

Definition InstCombineCasts.cpp:1742

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

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

Instruction * visitFPToSI(FPToSIInst &FI)

Definition InstCombineCasts.cpp:2315

Instruction * visitTrunc(TruncInst &CI)

Definition InstCombineCasts.cpp:970

Instruction * visitUIToFP(CastInst &CI)

Definition InstCombineCasts.cpp:2325

Instruction * visitPtrToInt(PtrToIntInst &CI)

Definition InstCombineCasts.cpp:2423

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

Instruction * visitSIToFP(CastInst &CI)

Definition InstCombineCasts.cpp:2335

Instruction * commonCastTransforms(CastInst &CI)

Implement the transforms common to all CastInst visitors.

Definition InstCombineCasts.cpp:190

Instruction * eraseInstFromFunction(Instruction &I) override

Combiner aware instruction erasure.

Instruction * foldItoFPtoI(CastInst &FI)

fpto{s/u}i({u/s}itofp(X)) --> X or zext(X) or sext(X) or trunc(X) This is safe if the intermediate ty...

Definition InstCombineCasts.cpp:2253

Instruction * visitFPTrunc(FPTruncInst &CI)

Definition InstCombineCasts.cpp:2047

Value * foldPtrToIntOrAddrOfGEP(Type *IntTy, Value *Ptr)

Definition InstCombineCasts.cpp:2387

Instruction * visitBitCast(BitCastInst &CI)

Definition InstCombineCasts.cpp:3086

Instruction * visitIntToPtr(IntToPtrInst &CI)

Definition InstCombineCasts.cpp:2347

Instruction * visitFPToUI(FPToUIInst &FI)

Definition InstCombineCasts.cpp:2305

Instruction * visitPtrToAddr(PtrToAddrInst &CI)

Definition InstCombineCasts.cpp:2466

Value * EvaluateInDifferentType(Value *V, Type *Ty, bool isSigned)

Given an expression that CanEvaluateTruncated or CanEvaluateSExtd returns true for,...

Definition InstCombineCasts.cpp:158

bool SimplifyDemandedInstructionBits(Instruction &Inst)

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

Instruction * visitFPExt(CastInst &CI)

Definition InstCombineCasts.cpp:2235

LoadInst * combineLoadToNewType(LoadInst &LI, Type *NewTy, const Twine &Suffix="")

Helper to combine a load to a new type.

The core instruction combiner logic.

const DataLayout & getDataLayout() const

unsigned ComputeMaxSignificantBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const

IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy

An IRBuilder that automatically inserts new instructions into the worklist.

unsigned ComputeNumSignBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const

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

A combiner-aware RAUW-like routine.

InstructionWorklist & Worklist

A worklist of the instructions that need to be simplified.

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

Same as InsertNewInstBefore, but also sets the debug loc.

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

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

const SimplifyQuery & getSimplifyQuery() const

LLVM_ABI void copyFastMathFlags(FastMathFlags FMF)

Convenience function for transferring all fast-math flag values to this instruction,...

static bool isBitwiseLogicOp(unsigned Opcode)

Determine if the Opcode is and/or/xor.

LLVM_ABI const Module * getModule() const

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

Instruction * user_back()

Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...

LLVM_ABI const Function * getFunction() const

Return the function this instruction belongs to.

LLVM_ABI void setNonNeg(bool b=true)

Set or clear the nneg flag on this instruction, which must be a zext instruction.

LLVM_ABI bool hasNonNeg() const LLVM_READONLY

Determine whether the the nneg 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...

unsigned getOpcode() const

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

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.

This class represents a cast from an integer to a pointer.

unsigned getAddressSpace() const

Returns the address space of this instruction's pointer type.

static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)

This static method is the primary way of constructing an IntegerType.

A wrapper class for inspecting calls to intrinsic functions.

This is an important class for using LLVM in a threaded context.

void addIncoming(Value *V, BasicBlock *BB)

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

op_range incoming_values()

BasicBlock * getIncomingBlock(unsigned i) const

Return incoming basic block number i.

Value * getIncomingValue(unsigned i) const

Return incoming value number x.

unsigned getNumIncomingValues() const

Return the number of incoming edges.

static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...

static LLVM_ABI PoisonValue * get(Type *T)

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

This class represents a cast from a pointer to an address (non-capturing ptrtoint).

Value * getPointerOperand()

Gets the pointer operand.

This class represents a cast from a pointer to an integer.

Value * getPointerOperand()

Gets the pointer operand.

unsigned getPointerAddressSpace() const

Returns the address space of the pointer operand.

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)

bool insert(const value_type &X)

Insert a new element into the SetVector.

This instruction constructs a fixed permutation of two input vectors.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

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

This class represents a truncation of integer types.

void setHasNoSignedWrap(bool B)

void setHasNoUnsignedWrap(bool B)

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.

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

bool isVectorTy() const

True if this is an instance of VectorType.

static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

bool isIntOrIntVectorTy() const

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

LLVM_ABI unsigned getPointerAddressSpace() const

Get the address space of this pointer or pointer vector type.

Type * getScalarType() const

If this is a vector type, return the element type, otherwise return 'this'.

LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

Return the basic size of this type if it is a primitive type.

LLVM_ABI Type * getWithNewType(Type *EltTy) const

Given vector type, change the element type, whilst keeping the old number of elements.

LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY

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

bool isPtrOrPtrVectorTy() const

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

bool isX86_AMXTy() const

Return true if this is X86 AMX.

bool isIntegerTy() const

True if this is an instance of IntegerType.

static LLVM_ABI Type * getDoubleTy(LLVMContext &C)

bool isFPOrFPVectorTy() const

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

static LLVM_ABI Type * getFloatTy(LLVMContext &C)

LLVM_ABI int getFPMantissaWidth() const

Return the width of the mantissa of this type.

LLVM_ABI const fltSemantics & getFltSemantics() const

static LLVM_ABI Type * getBFloatTy(LLVMContext &C)

static LLVM_ABI Type * getHalfTy(LLVMContext &C)

'undef' values are things that do not have specified contents.

static LLVM_ABI UndefValue * get(Type *T)

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

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 LLVMContext & getContext() const

All values hold a context through their type.

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.

static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)

This static method is the primary way to construct an VectorType.

static LLVM_ABI bool isValidElementType(Type *ElemTy)

Return true if the specified type is valid as a element type.

This class represents zero extension of integer types.

static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)

#define llvm_unreachable(msg)

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

constexpr std::underlying_type_t< E > Mask()

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

@ C

The default llvm calling convention, compatible with C.

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

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

SpecificConstantMatch m_ZeroInt()

Convenience matchers for specific integer values.

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

Matches a register negated by a G_SUB.

OneUse_match< SubPat > m_OneUse(const SubPat &SP)

cst_pred_ty< is_lowbit_mask > m_LowBitMask()

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

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

PtrToIntSameSize_match< OpTy > m_PtrToIntSameSize(const DataLayout &DL, const OpTy &Op)

class_match< BinaryOperator > m_BinOp()

Match an arbitrary binary operation and ignore it.

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)

cst_pred_ty< is_power2 > m_Power2()

Match an integer or vector power-of-2.

class_match< Constant > m_Constant()

Match an arbitrary Constant and ignore it.

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

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

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

Matches an And with LHS and RHS in either order.

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

Matches Trunc.

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

specific_intval< false > m_SpecificInt(const APInt &V)

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

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

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)

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

Matches ExtractElementInst.

class_match< ConstantInt > m_ConstantInt()

Match an arbitrary ConstantInt and ignore it.

cst_pred_ty< is_one > m_One()

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

IntrinsicID_match m_Intrinsic()

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

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

Matches SelectInst.

IntrinsicID_match m_VScale()

Matches a call to llvm.vscale().

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

Matches logical shift operations.

CastInst_match< OpTy, FPToUIInst > m_FPToUI(const OpTy &Op)

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

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

Matches ShuffleVectorInst independently of mask value.

CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)

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

Matches ZExt.

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.

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

Matches a Add with LHS and RHS in either order.

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

Matches BitCast.

CastInst_match< OpTy, FPToSIInst > m_FPToSI(const OpTy &Op)

class_match< Value > m_Value()

Match an arbitrary value and ignore it.

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)

FNeg_match< OpTy > m_FNeg(const OpTy &X)

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

BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)

Matches shift operations.

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

auto m_Undef()

Match an arbitrary undef constant.

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

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

Matches SExt.

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

Matches an Or with LHS and RHS in either order.

CastOperator_match< OpTy, Instruction::IntToPtr > m_IntToPtr(const OpTy &Op)

Matches IntToPtr.

ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)

Matches InsertElementInst.

ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)

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

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

Combine two pattern matchers matching L || R.

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

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

friend class Instruction

Iterator for Instructions in a `BasicBlock.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)

Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.

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 Constant * ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2)

Attempt to constant fold a select instruction with the specified operands.

decltype(auto) dyn_cast(const From &Val)

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

unsigned Log2_64_Ceil(uint64_t Value)

Return the ceil log base 2 of the specified value, 64 if the value is zero.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

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

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

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)

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

auto dyn_cast_or_null(const Y &Val)

unsigned Log2_32(uint32_t Value)

Return the floor log base 2 of the specified value, -1 if the value is zero.

auto reverse(ContainerTy &&C)

constexpr bool isPowerOf2_32(uint32_t Value)

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

FPClassTest

Floating-point class tests, supported by 'is_fpclass' intrinsic.

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

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

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)

Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...

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

Attempt to constant fold a cast with the specified operand.

class LLVM_GSL_OWNER SmallVector

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

bool isa(const From &Val)

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

LLVM_ABI bool replaceAllDbgUsesWith(Instruction &From, Value &To, Instruction &DomPoint, DominatorTree &DT)

Point debug users of From to To or salvage them.

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

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

@ And

Bitwise or logical AND of integers.

DWARFExpression::Operation Op

constexpr unsigned BitWidth

decltype(auto) cast(const From &Val)

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

bool all_equal(std::initializer_list< T > Values)

Returns true if all Values in the initializer lists are equal or the list.

auto seq(T Begin, T End)

Iterate over an integral type from Begin up to - but not including - End.

LLVM_ABI Constant * ConstantFoldIntegerCast(Constant *C, Type *DestTy, bool IsSigned, const DataLayout &DL)

Constant fold a zext, sext or trunc, depending on IsSigned and whether the DestTy is wider or narrowe...

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 Constant * ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2)

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

Implement std::swap in terms of BitVector swap.

unsigned countMinTrailingZeros() const

Returns the minimum number of trailing zero bits.

unsigned countMinLeadingZeros() const

Returns the minimum number of leading zero bits.

APInt getMaxValue() const

Return the maximal unsigned value possible given these KnownBits.

bool isKnownNever(FPClassTest Mask) const

Return true if it's known this can never be one of the mask entries.

SimplifyQuery getWithInstruction(const Instruction *I) const