LLVM: lib/IR/ConstantFold.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

32using namespace llvm;

34

35

36

37

38

39

40

41

42

43static unsigned

45 unsigned opc,

46 ConstantExpr *Op,

47 Type *DstTy

  1. {

49 assert(Op && Op->isCast() && "Can't fold cast of cast without a cast!");

51 assert(CastInst::isCast(opc) && "Invalid cast opcode");

52

53

54 Type *SrcTy = Op->getOperand(0)->getType();

55 Type *MidTy = Op->getType();

58

59

60

61

63

64

66 nullptr, FakeIntPtrTy, nullptr);

67}

68

70 Type *SrcTy = V->getType();

71 if (SrcTy == DestTy)

72 return V;

73

74 if (V->isAllOnesValue())

76

77

78 if (ConstantInt *CI = dyn_cast(V)) {

79

80

81

82 if (isa(DestTy) && !isa(SrcTy))

84

85

86

89 return nullptr;

90

91 return ConstantFP::get(

92 DestTy,

94 }

95

96

97 if (ConstantFP *FP = dyn_cast(V)) {

98

99

100

101 if (isa(DestTy) && !isa(SrcTy))

103

104

105

106

107

108

109

111 return nullptr;

112

113

116 return nullptr;

117

118 return ConstantInt::get(DestTy, FP->getValueAPF().bitcastToAPInt());

119 }

120

121 return nullptr;

122}

123

125 Type *DestTy) {

129}

130

132 Type *DestTy) {

133 if (isa(V))

135

136 if (isa(V)) {

137

138

139

140 if (opc == Instruction::ZExt || opc == Instruction::SExt ||

141 opc == Instruction::UIToFP || opc == Instruction::SIToFP)

144 }

145

146 if (V->isNullValue() && !DestTy->isX86_AMXTy() &&

147 opc != Instruction::AddrSpaceCast)

149

150

151

152 if (ConstantExpr *CE = dyn_cast(V)) {

153 if (CE->isCast()) {

154

157 }

158 }

159

160

161

162

163 if ((isa(V) || isa(V)) &&

165 cast(DestTy)->getNumElements() ==

166 cast(V->getType())->getNumElements()) {

167 VectorType *DestVecTy = cast(DestTy);

169

172 if (!Res)

173 return nullptr;

175 cast(DestTy)->getElementCount(), Res);

176 }

179 for (unsigned i = 0,

180 e = cast(V->getType())->getNumElements();

181 i != e; ++i) {

184 if (!Casted)

185 return nullptr;

187 }

189 }

190

191

192

193 switch (opc) {

194 default:

196 case Instruction::FPTrunc:

197 case Instruction::FPExt:

198 if (ConstantFP *FPC = dyn_cast(V)) {

200 APFloat Val = FPC->getValueAPF();

202 APFloat::rmNearestTiesToEven, &ignored);

203 return ConstantFP::get(DestTy, Val);

204 }

205 return nullptr;

206 case Instruction::FPToUI:

207 case Instruction::FPToSI:

208 if (ConstantFP *FPC = dyn_cast(V)) {

209 const APFloat &V = FPC->getValueAPF();

212 if (APFloat::opInvalidOp ==

213 V.convertToInteger(IntVal, APFloat::rmTowardZero, &ignored)) {

214

215

217 }

218 return ConstantInt::get(DestTy, IntVal);

219 }

220 return nullptr;

221 case Instruction::UIToFP:

222 case Instruction::SIToFP:

223 if (ConstantInt *CI = dyn_cast(V)) {

224 const APInt &api = CI->getValue();

228 APFloat::rmNearestTiesToEven);

229 return ConstantFP::get(DestTy, apf);

230 }

231 return nullptr;

232 case Instruction::ZExt:

233 if (ConstantInt *CI = dyn_cast(V)) {

235 return ConstantInt::get(DestTy, CI->getValue().zext(BitWidth));

236 }

237 return nullptr;

238 case Instruction::SExt:

239 if (ConstantInt *CI = dyn_cast(V)) {

241 return ConstantInt::get(DestTy, CI->getValue().sext(BitWidth));

242 }

243 return nullptr;

244 case Instruction::Trunc: {

245 if (ConstantInt *CI = dyn_cast(V)) {

247 return ConstantInt::get(DestTy, CI->getValue().trunc(BitWidth));

248 }

249

250 return nullptr;

251 }

252 case Instruction::BitCast:

254 case Instruction::AddrSpaceCast:

255 case Instruction::IntToPtr:

256 case Instruction::PtrToInt:

257 return nullptr;

258 }

259}

260

263

264 if (Cond->isNullValue()) return V2;

265 if (Cond->isAllOnesValue()) return V1;

266

267

269 auto *V1VTy = CondV->getType();

272 for (unsigned i = 0, e = V1VTy->getNumElements(); i != e; ++i) {

275 ConstantInt::get(Ty, i));

277 ConstantInt::get(Ty, i));

278 auto *Cond = cast(CondV->getOperand(i));

279 if (isa(Cond)) {

281 } else if (V1Element == V2Element) {

282 V = V1Element;

283 } else if (isa(Cond)) {

284 V = isa(V1Element) ? V1Element : V2Element;

285 } else {

286 if (!isa(Cond)) break;

287 V = Cond->isNullValue() ? V2Element : V1Element;

288 }

289 Result.push_back(V);

290 }

291

292

293 if (Result.size() == V1VTy->getNumElements())

295 }

296

297 if (isa(Cond))

299

300 if (isa(Cond)) {

301 if (isa(V1)) return V1;

302 return V2;

303 }

304

305 if (V1 == V2) return V1;

306

307 if (isa(V1))

308 return V2;

309 if (isa(V2))

310 return V1;

311

312

313

314 auto NotPoison = [](Constant *C) {

315 if (isa(C))

316 return false;

317

318

319

320 if (isa(C))

321 return false;

322

323 if (isa(C) || isa(C) || isa(C) ||

324 isa(C) || isa(C))

325 return true;

326

327 if (C->getType()->isVectorTy())

328 return C->containsPoisonElement() && C->containsConstantExpression();

329

330

331 return false;

332 };

333 if (isa(V1) && NotPoison(V2)) return V2;

334 if (isa(V2) && NotPoison(V1)) return V1;

335

336 return nullptr;

337}

338

341 auto *ValVTy = cast(Val->getType());

342

343

344

345 if (isa(Val) || isa(Idx))

347

348

349 if (isa(Val))

351

352 auto *CIdx = dyn_cast(Idx);

353 if (!CIdx)

354 return nullptr;

355

356 if (auto *ValFVTy = dyn_cast(Val->getType())) {

357

358 if (CIdx->uge(ValFVTy->getNumElements()))

360 }

361

362

363 if (auto *CE = dyn_cast(Val)) {

364 if (auto *GEP = dyn_cast(CE)) {

366 Ops.reserve(CE->getNumOperands());

367 for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {

369 if (Op->getType()->isVectorTy()) {

371 if (!ScalarOp)

372 return nullptr;

374 } else

376 }

377 return CE->getWithOperands(Ops, ValVTy->getElementType(), false,

378 GEP->getSourceElementType());

379 } else if (CE->getOpcode() == Instruction::InsertElement) {

380 if (const auto *IEIdx = dyn_cast(CE->getOperand(2))) {

382 APSInt(CIdx->getValue()))) {

383 return CE->getOperand(1);

384 } else {

386 }

387 }

388 }

389 }

390

392 return C;

393

394

395 if (CIdx->getValue().ult(ValVTy->getElementCount().getKnownMinValue())) {

397 return SplatVal;

398 }

399

400 return nullptr;

401}

402

406 if (isa(Idx))

408

409

410

411 if (isa(Val) && Elt->isNullValue())

412 return Val;

413

415 if (!CIdx) return nullptr;

416

417

418

419 if (isa(Val->getType()))

420 return nullptr;

421

422 auto *ValTy = cast(Val->getType());

423

424 unsigned NumElts = ValTy->getNumElements();

425 if (CIdx->uge(NumElts))

427

429 Result.reserve(NumElts);

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

433 if (i == IdxVal) {

434 Result.push_back(Elt);

435 continue;

436 }

437

439 Result.push_back(C);

440 }

441

443}

444

447 auto *V1VTy = cast(V1->getType());

448 unsigned MaskNumElts = Mask.size();

449 auto MaskEltCount =

451 Type *EltTy = V1VTy->getElementType();

452

453

455 return PoisonValue::get(VectorType::get(EltTy, MaskEltCount));

456 }

457

458

459

460 if (all_of(Mask, [](int Elt) { return Elt == 0; })) {

464

466 auto *VTy = VectorType::get(EltTy, MaskEltCount);

468 } else if (!MaskEltCount.isScalable())

470 }

471

472

473

474 if (isa(V1VTy))

475 return nullptr;

476

477 unsigned SrcNumElts = V1VTy->getElementCount().getKnownMinValue();

478

479

481 for (unsigned i = 0; i != MaskNumElts; ++i) {

482 int Elt = Mask[i];

483 if (Elt == -1) {

485 continue;

486 }

488 if (unsigned(Elt) >= SrcNumElts*2)

490 else if (unsigned(Elt) >= SrcNumElts) {

492 InElt =

494 ConstantInt::get(Ty, Elt - SrcNumElts));

495 } else {

498 }

499 Result.push_back(InElt);

500 }

501

503}

504

507

508 if (Idxs.empty())

509 return Agg;

510

513

514 return nullptr;

515}

516

520

521 if (Idxs.empty())

522 return Val;

523

524 unsigned NumElts;

526 NumElts = ST->getNumElements();

527 else

528 NumElts = cast(Agg->getType())->getNumElements();

529

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

533 if (C) return nullptr;

534

535 if (Idxs[0] == i)

537

538 Result.push_back(C);

539 }

540

544}

545

548

549

550

551 bool IsScalableVector = isa(C->getType());

552 bool HasScalarUndefOrScalableVectorUndef =

553 (C->getType()->isVectorTy() || IsScalableVector) && isa(C);

554

555 if (HasScalarUndefOrScalableVectorUndef) {

557 case Instruction::FNeg:

558 return C;

559 case Instruction::UnaryOpsEnd:

561 }

562 }

563

564

565 assert(!HasScalarUndefOrScalableVectorUndef && "Unexpected UndefValue");

566

567 assert(!isa(C) && "Unexpected Integer UnaryOp");

568

569 if (ConstantFP *CFP = dyn_cast(C)) {

570 const APFloat &CV = CFP->getValueAPF();

571 switch (Opcode) {

572 default:

573 break;

574 case Instruction::FNeg:

575 return ConstantFP::get(C->getType(), neg(CV));

576 }

577 } else if (auto *VTy = dyn_cast(C->getType())) {

578

582

583 if (auto *FVTy = dyn_cast(VTy)) {

584

587 for (unsigned i = 0, e = FVTy->getNumElements(); i != e; ++i) {

588 Constant *ExtractIdx = ConstantInt::get(Ty, i);

591 if (!Res)

592 return nullptr;

593 Result.push_back(Res);

594 }

595

597 }

598 }

599

600

601 return nullptr;

602}

603

607

608

609

611 Opcode, C1->getType(), false)) {

612 if (C1 == Identity)

613 return C2;

614 if (C2 == Identity)

615 return C1;

617 Opcode, C1->getType(), true)) {

618 if (C2 == Identity)

619 return C1;

620 }

621

622

623 if (isa(C1) || isa(C2))

625

626

627

628 bool IsScalableVector = isa(C1->getType());

629 bool HasScalarUndefOrScalableVectorUndef =

631 (isa(C1) || isa(C2));

632 if (HasScalarUndefOrScalableVectorUndef) {

634 case Instruction::Xor:

635 if (isa(C1) && isa(C2))

636

637

639 [[fallthrough]];

640 case Instruction::Add:

641 case Instruction::Sub:

643 case Instruction::And:

644 if (isa(C1) && isa(C2))

645 return C1;

647 case Instruction::Mul: {

648

649 if (isa(C1) && isa(C2))

650 return C1;

652

654 if ((*CV)[0])

656

657

659 }

660 case Instruction::SDiv:

661 case Instruction::UDiv:

662

663

666

668 case Instruction::URem:

669 case Instruction::SRem:

670

671

674

676 case Instruction::Or:

677 if (isa(C1) && isa(C2))

678 return C1;

680 case Instruction::LShr:

681

682 if (isa(C2))

684

686 case Instruction::AShr:

687

688 if (isa(C2))

690

691

693 case Instruction::Shl:

694

695 if (isa(C2))

697

699 case Instruction::FSub:

700

702 return C2;

703 [[fallthrough]];

704 case Instruction::FAdd:

705 case Instruction::FMul:

706 case Instruction::FDiv:

707 case Instruction::FRem:

708

709 if (isa(C1) && isa(C2))

710 return C1;

711

712

713

714

715

716

717

719 case Instruction::BinaryOpsEnd:

721 }

722 }

723

724

725 assert((!HasScalarUndefOrScalableVectorUndef) && "Unexpected UndefValue");

726

727

728 if (ConstantInt *CI2 = dyn_cast(C2)) {

730 false))

731 return C2;

732

733 switch (Opcode) {

734 case Instruction::UDiv:

735 case Instruction::SDiv:

736 if (CI2->isZero())

738 break;

739 case Instruction::URem:

740 case Instruction::SRem:

741 if (CI2->isOne())

743 if (CI2->isZero())

745 break;

746 case Instruction::And:

747 assert(!CI2->isZero() && "And zero handled above");

748 if (ConstantExpr *CE1 = dyn_cast(C1)) {

749

750 if (CE1->getOpcode() == Instruction::PtrToInt &&

751 isa(CE1->getOperand(0))) {

752 GlobalValue *GV = cast(CE1->getOperand(0));

753

754 Align GVAlign;

755

757 const DataLayout &DL = TheModule->getDataLayout();

759

760

761

762

763

764

765

766

767

768

769 if (isa(GV) && DL.getFunctionPtrAlign())

770 GVAlign = Align(4);

771 } else if (isa(GV)) {

772 GVAlign = cast(GV)->getAlign().valueOrOne();

773 }

774

775 if (GVAlign > 1) {

776 unsigned DstWidth = CI2->getBitWidth();

777 unsigned SrcWidth = std::min(DstWidth, Log2(GVAlign));

779

780

781 if ((CI2->getValue() & BitsNotSet) == CI2->getValue())

783 }

784 }

785 }

786 break;

787 }

788 } else if (isa(C1)) {

789

794 }

795

796 if (ConstantInt *CI1 = dyn_cast(C1)) {

797 if (ConstantInt *CI2 = dyn_cast(C2)) {

798 const APInt &C1V = CI1->getValue();

799 const APInt &C2V = CI2->getValue();

800 switch (Opcode) {

801 default:

802 break;

803 case Instruction::Add:

804 return ConstantInt::get(C1->getType(), C1V + C2V);

805 case Instruction::Sub:

806 return ConstantInt::get(C1->getType(), C1V - C2V);

807 case Instruction::Mul:

808 return ConstantInt::get(C1->getType(), C1V * C2V);

809 case Instruction::UDiv:

810 assert(!CI2->isZero() && "Div by zero handled above");

811 return ConstantInt::get(CI1->getType(), C1V.udiv(C2V));

812 case Instruction::SDiv:

813 assert(!CI2->isZero() && "Div by zero handled above");

815 return PoisonValue::get(CI1->getType());

816 return ConstantInt::get(CI1->getType(), C1V.sdiv(C2V));

817 case Instruction::URem:

818 assert(!CI2->isZero() && "Div by zero handled above");

819 return ConstantInt::get(C1->getType(), C1V.urem(C2V));

820 case Instruction::SRem:

821 assert(!CI2->isZero() && "Div by zero handled above");

824 return ConstantInt::get(C1->getType(), C1V.srem(C2V));

825 case Instruction::And:

826 return ConstantInt::get(C1->getType(), C1V & C2V);

827 case Instruction::Or:

828 return ConstantInt::get(C1->getType(), C1V | C2V);

829 case Instruction::Xor:

830 return ConstantInt::get(C1->getType(), C1V ^ C2V);

831 case Instruction::Shl:

833 return ConstantInt::get(C1->getType(), C1V.shl(C2V));

835 case Instruction::LShr:

837 return ConstantInt::get(C1->getType(), C1V.lshr(C2V));

839 case Instruction::AShr:

841 return ConstantInt::get(C1->getType(), C1V.ashr(C2V));

843 }

844 }

845

847 true))

848 return C1;

849 } else if (ConstantFP *CFP1 = dyn_cast(C1)) {

850 if (ConstantFP *CFP2 = dyn_cast(C2)) {

851 const APFloat &C1V = CFP1->getValueAPF();

852 const APFloat &C2V = CFP2->getValueAPF();

853 APFloat C3V = C1V;

854 switch (Opcode) {

855 default:

856 break;

857 case Instruction::FAdd:

858 (void)C3V.add(C2V, APFloat::rmNearestTiesToEven);

859 return ConstantFP::get(C1->getType(), C3V);

860 case Instruction::FSub:

861 (void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven);

862 return ConstantFP::get(C1->getType(), C3V);

863 case Instruction::FMul:

864 (void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven);

865 return ConstantFP::get(C1->getType(), C3V);

866 case Instruction::FDiv:

867 (void)C3V.divide(C2V, APFloat::rmNearestTiesToEven);

868 return ConstantFP::get(C1->getType(), C3V);

869 case Instruction::FRem:

870 (void)C3V.mod(C2V);

871 return ConstantFP::get(C1->getType(), C3V);

872 }

873 }

874 }

875

876 if (auto *VTy = dyn_cast(C1->getType())) {

877

886 if (!Res)

887 return nullptr;

889 }

890 }

891

892 if (auto *FVTy = dyn_cast(VTy)) {

893

896 for (unsigned i = 0, e = FVTy->getNumElements(); i != e; ++i) {

897 Constant *ExtractIdx = ConstantInt::get(Ty, i);

903 if (!Res)

904 return nullptr;

905 Result.push_back(Res);

906 }

907

909 }

910 }

911

912 if (ConstantExpr *CE1 = dyn_cast(C1)) {

913

914

915

916

917

918

921 if (!isa(T) || cast(T)->getOpcode() != Opcode)

923 }

924 } else if (isa(C2)) {

925

926

929 }

930

931

933 switch (Opcode) {

934 case Instruction::Add:

935 case Instruction::Sub:

937 case Instruction::Shl:

938 case Instruction::LShr:

939 case Instruction::AShr:

940

941

942 return C1;

943 case Instruction::SDiv:

944 case Instruction::UDiv:

945

946

947 return C1;

948 case Instruction::URem:

949 case Instruction::SRem:

950

951

953 default:

954 break;

955 }

956 }

957

958

959 return nullptr;

960}

961

964 auto isGlobalUnsafeForEquality = [](const GlobalValue *GV) {

965 if (GV->isInterposable() || GV->hasGlobalUnnamedAddr())

966 return true;

967 if (const auto *GVar = dyn_cast(GV)) {

968 Type *Ty = GVar->getValueType();

969

971 return true;

972

973

975 return true;

976 }

977 return false;

978 };

979

980 if (!isa(GV1) && !isa(GV2))

981 if (!isGlobalUnsafeForEquality(GV1) && !isGlobalUnsafeForEquality(GV2))

982 return ICmpInst::ICMP_NE;

983 return ICmpInst::BAD_ICMP_PREDICATE;

984}

985

986

987

988

989

990

991

994 "Cannot compare different types of values!");

995 if (V1 == V2) return ICmpInst::ICMP_EQ;

996

997

999 return ICmpInst::BAD_ICMP_PREDICATE;

1000

1001

1002

1003

1004

1005 auto GetComplexity = [](Constant *V) {

1006 if (isa(V))

1007 return 3;

1008 if (isa(V))

1009 return 2;

1010 if (isa(V))

1011 return 1;

1012 return 0;

1013 };

1014 if (GetComplexity(V1) < GetComplexity(V2)) {

1016 if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE)

1017 return ICmpInst::getSwappedPredicate(SwappedRelation);

1018 return ICmpInst::BAD_ICMP_PREDICATE;

1019 }

1020

1021 if (const BlockAddress *BA = dyn_cast(V1)) {

1022

1023 if (const BlockAddress *BA2 = dyn_cast(V2)) {

1024

1025

1026

1027 if (BA2->getFunction() != BA->getFunction())

1028 return ICmpInst::ICMP_NE;

1029 } else if (isa(V2)) {

1030 return ICmpInst::ICMP_NE;

1031 }

1032 } else if (const GlobalValue *GV = dyn_cast(V1)) {

1033

1034

1035 if (const GlobalValue *GV2 = dyn_cast(V2)) {

1037 } else if (isa(V2)) {

1038 return ICmpInst::ICMP_NE;

1039 } else if (isa(V2)) {

1040

1041

1042

1043

1044

1045 if (!GV->hasExternalWeakLinkage() && !isa(GV) &&

1047 GV->getType()->getAddressSpace()))

1048 return ICmpInst::ICMP_UGT;

1049 }

1050 } else if (auto *CE1 = dyn_cast(V1)) {

1051

1052

1054

1055 switch (CE1->getOpcode()) {

1056 case Instruction::GetElementPtr: {

1057 GEPOperator *CE1GEP = cast(CE1);

1058

1059

1060 if (isa(V2)) {

1061

1062

1063 if (const GlobalValue *GV = dyn_cast(CE1Op0)) {

1064

1065

1066 if (!GV->hasExternalWeakLinkage() && CE1GEP->isInBounds())

1067 return ICmpInst::ICMP_UGT;

1068 }

1069 } else if (const GlobalValue *GV2 = dyn_cast(V2)) {

1070 if (const GlobalValue *GV = dyn_cast(CE1Op0)) {

1071 if (GV != GV2) {

1074 return ICmpInst::BAD_ICMP_PREDICATE;

1075 }

1076 }

1077 } else if (const auto *CE2GEP = dyn_cast(V2)) {

1078

1079

1080 const Constant *CE2Op0 = cast(CE2GEP->getPointerOperand());

1081 if (isa(CE1Op0) && isa(CE2Op0)) {

1082

1083 if (CE1Op0 != CE2Op0) {

1086 cast(CE2Op0));

1087 return ICmpInst::BAD_ICMP_PREDICATE;

1088 }

1089 }

1090 }

1091 break;

1092 }

1093 default:

1094 break;

1095 }

1096 }

1097

1098 return ICmpInst::BAD_ICMP_PREDICATE;

1099}

1100

1103 Type *ResultTy;

1106 VT->getElementCount());

1107 else

1109

1110

1111 if (Predicate == FCmpInst::FCMP_FALSE)

1113

1114 if (Predicate == FCmpInst::FCMP_TRUE)

1116

1117

1118 if (isa(C1) || isa(C2))

1120

1121 if (isa(C1) || isa(C2)) {

1122 bool isIntegerPredicate = ICmpInst::isIntPredicate(Predicate);

1123

1124

1125

1128

1129

1130

1131 if (isIntegerPredicate)

1133

1134

1135

1137 }

1138

1140

1141

1142

1143 if (Predicate == ICmpInst::ICMP_UGE)

1145

1146 if (Predicate == ICmpInst::ICMP_ULT)

1148 }

1149

1150

1152 switch (Predicate) {

1153 case ICmpInst::ICMP_EQ:

1154 if (isa(C2))

1157 case ICmpInst::ICMP_NE:

1159 default:

1160 break;

1161 }

1162 }

1163

1164 if (isa(C1) && isa(C2)) {

1165 const APInt &V1 = cast(C1)->getValue();

1166 const APInt &V2 = cast(C2)->getValue();

1167 return ConstantInt::get(ResultTy, ICmpInst::compare(V1, V2, Predicate));

1168 } else if (isa(C1) && isa(C2)) {

1169 const APFloat &C1V = cast(C1)->getValueAPF();

1170 const APFloat &C2V = cast(C2)->getValueAPF();

1171 return ConstantInt::get(ResultTy, FCmpInst::compare(C1V, C2V, Predicate));

1172 } else if (auto *C1VTy = dyn_cast(C1->getType())) {

1173

1174

1180

1181

1182

1183 if (isa(C1VTy))

1184 return nullptr;

1185

1186

1187

1190

1191 for (unsigned I = 0, E = C1VTy->getElementCount().getKnownMinValue();

1192 I != E; ++I) {

1198 if (!Elt)

1199 return nullptr;

1200

1202 }

1203

1205 }

1206

1208 if (C1 == C2) {

1209

1210 if (Predicate == FCmpInst::FCMP_ONE)

1212 else if (Predicate == FCmpInst::FCMP_UEQ)

1214 }

1215 } else {

1216

1217 int Result = -1;

1220 case ICmpInst::BAD_ICMP_PREDICATE:

1221 break;

1222 case ICmpInst::ICMP_EQ:

1223

1224

1225 Result = ICmpInst::isTrueWhenEqual(Predicate);

1226 break;

1227 case ICmpInst::ICMP_ULT:

1228 switch (Predicate) {

1229 case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_ULE:

1230 Result = 1; break;

1231 case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_UGE:

1232 Result = 0; break;

1233 default:

1234 break;

1235 }

1236 break;

1237 case ICmpInst::ICMP_SLT:

1238 switch (Predicate) {

1239 case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_SLE:

1240 Result = 1; break;

1241 case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_SGE:

1242 Result = 0; break;

1243 default:

1244 break;

1245 }

1246 break;

1247 case ICmpInst::ICMP_UGT:

1248 switch (Predicate) {

1249 case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_UGE:

1250 Result = 1; break;

1251 case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_ULE:

1252 Result = 0; break;

1253 default:

1254 break;

1255 }

1256 break;

1257 case ICmpInst::ICMP_SGT:

1258 switch (Predicate) {

1259 case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_SGE:

1260 Result = 1; break;

1261 case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_SLE:

1262 Result = 0; break;

1263 default:

1264 break;

1265 }

1266 break;

1267 case ICmpInst::ICMP_ULE:

1268 if (Predicate == ICmpInst::ICMP_UGT)

1269 Result = 0;

1270 if (Predicate == ICmpInst::ICMP_ULT || Predicate == ICmpInst::ICMP_ULE)

1271 Result = 1;

1272 break;

1273 case ICmpInst::ICMP_SLE:

1274 if (Predicate == ICmpInst::ICMP_SGT)

1275 Result = 0;

1276 if (Predicate == ICmpInst::ICMP_SLT || Predicate == ICmpInst::ICMP_SLE)

1277 Result = 1;

1278 break;

1279 case ICmpInst::ICMP_UGE:

1280 if (Predicate == ICmpInst::ICMP_ULT)

1281 Result = 0;

1282 if (Predicate == ICmpInst::ICMP_UGT || Predicate == ICmpInst::ICMP_UGE)

1283 Result = 1;

1284 break;

1285 case ICmpInst::ICMP_SGE:

1286 if (Predicate == ICmpInst::ICMP_SLT)

1287 Result = 0;

1288 if (Predicate == ICmpInst::ICMP_SGT || Predicate == ICmpInst::ICMP_SGE)

1289 Result = 1;

1290 break;

1291 case ICmpInst::ICMP_NE:

1292 if (Predicate == ICmpInst::ICMP_EQ)

1293 Result = 0;

1294 if (Predicate == ICmpInst::ICMP_NE)

1295 Result = 1;

1296 break;

1297 }

1298

1299

1300 if (Result != -1)

1301 return ConstantInt::get(ResultTy, Result);

1302

1303 if ((!isa(C1) && isa(C2)) ||

1305

1306

1307

1308 Predicate = ICmpInst::getSwappedPredicate(Predicate);

1310 }

1311 }

1312 return nullptr;

1313}

1314

1316 std::optional InRange,

1318 if (Idxs.empty()) return C;

1319

1322

1323 if (isa(C))

1325

1326 if (isa(C))

1328

1329 auto IsNoOp = [&]() {

1330

1332 return false;

1333

1336 return IdxC->isNullValue() || isa(IdxC);

1337 });

1338 };

1339 if (IsNoOp())

1340 return GEPTy->isVectorTy() && C->getType()->isVectorTy()

1342 cast(GEPTy)->getElementCount(), C)

1343 : C;

1344

1345 return nullptr;

1346}

This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static unsigned foldConstantCastPair(unsigned opc, ConstantExpr *Op, Type *DstTy)

This function determines which opcode to use to fold two constant cast expressions together.

static Constant * foldMaybeUndesirableCast(unsigned opc, Constant *V, Type *DestTy)

static ICmpInst::Predicate areGlobalsPotentiallyEqual(const GlobalValue *GV1, const GlobalValue *GV2)

static Constant * FoldBitCast(Constant *V, Type *DestTy)

static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2)

This function determines if there is anything we can decide about the two constants provided.

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

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

Looks at all the uses of the given value Returns the Liveness deduced from the uses of this value Adds all uses that cause the result to be MaybeLive to MaybeLiveRetUses If the result is MaybeLiveUses might be modified but its content should be ignored(since it might not be complete). DeadArgumentEliminationPass

Module.h This file contains the declarations for the Module class.

static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)

const SmallVectorImpl< MachineOperand > & Cond

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

This file defines the SmallVector class.

static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)

Returns the opcode of Values or ~0 if they do not all agree.

opStatus divide(const APFloat &RHS, roundingMode RM)

opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)

opStatus subtract(const APFloat &RHS, roundingMode RM)

opStatus add(const APFloat &RHS, roundingMode RM)

opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM)

opStatus multiply(const APFloat &RHS, roundingMode RM)

opStatus mod(const APFloat &RHS)

Class for arbitrary precision integers.

APInt udiv(const APInt &RHS) const

Unsigned division operation.

bool isMinSignedValue() const

Determine if this is the smallest signed value.

APInt urem(const APInt &RHS) const

Unsigned remainder operation.

unsigned getBitWidth() const

Return the number of bits in the APInt.

APInt sdiv(const APInt &RHS) const

Signed division function for APInt.

APInt ashr(unsigned ShiftAmt) const

Arithmetic right-shift function.

APInt srem(const APInt &RHS) const

Function for signed remainder operation.

APInt shl(unsigned shiftAmt) const

Left-shift function.

static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)

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

static APInt getZero(unsigned numBits)

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

APInt lshr(unsigned shiftAmt) const

Logical right-shift function.

An arbitrary precision integer that knows its signedness.

static bool isSameValue(const APSInt &I1, const APSInt &I2)

Determine if two APSInts have the same value, zero- or sign-extending as needed.

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

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

ArrayRef< T > slice(size_t N, size_t M) const

slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.

The address of a basic block.

static unsigned isEliminableCastPair(Instruction::CastOps firstOpcode, Instruction::CastOps secondOpcode, Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy, Type *DstIntPtrTy)

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

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

bool isTrueWhenEqual() const

This is just a convenience.

static bool isUnordered(Predicate predicate)

Determine if the predicate is an unordered operation.

static ConstantAggregateZero * get(Type *Ty)

static Constant * get(ArrayType *T, ArrayRef< Constant * > V)

A constant value that is initialized with an expression using other constant values.

static Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)

static bool isDesirableCastOp(unsigned Opcode)

Whether creating a constant expression for this cast is desirable.

static Constant * getBinOpAbsorber(unsigned Opcode, Type *Ty, bool AllowLHSConstant=false)

Return the absorbing element for the given binary operation, i.e.

static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)

Convenience function for getting a Cast operation.

static Constant * getNot(Constant *C)

static Constant * getXor(Constant *C1, Constant *C2)

static Constant * get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags=0, Type *OnlyIfReducedTy=nullptr)

get - Return a binary or shift operator constant expression, folding if possible.

static bool isDesirableBinOp(unsigned Opcode)

Whether creating a constant expression for this binary operator is desirable.

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

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

Return the identity constant for a binary opcode.

ConstantFP - Floating Point Values [float, double].

static Constant * getNaN(Type *Ty, bool Negative=false, uint64_t Payload=0)

This is the shared class of boolean and integer constants.

static ConstantInt * getTrue(LLVMContext &Context)

static ConstantInt * getFalse(LLVMContext &Context)

uint64_t getZExtValue() const

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

bool uge(uint64_t Num) const

This function will return true iff this constant represents a value with active bits bigger than 64 b...

static Constant * get(StructType *T, ArrayRef< Constant * > V)

Constant Vector Declarations.

static Constant * getSplat(ElementCount EC, Constant *Elt)

Return a ConstantVector with the specified constant in each element.

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

This is an important base class in LLVM.

Constant * getSplatValue(bool AllowPoison=false) const

If all elements of the vector constant have the same value, return that value.

static Constant * getAllOnesValue(Type *Ty)

static Constant * getNullValue(Type *Ty)

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

Constant * getAggregateElement(unsigned Elt) const

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

bool isNullValue() const

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

This class represents an Operation in the Expression.

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

static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)

static bool compare(const APFloat &LHS, const APFloat &RHS, FCmpInst::Predicate Pred)

Return result of LHS Pred RHS comparison.

bool isInBounds() const

Test whether this is an inbounds GEP, as defined by LangRef.html.

bool hasAllZeroIndices() const

Return true if all of the indices of this GEP are zeros.

static Type * getGEPReturnType(Value *Ptr, ArrayRef< Value * > IdxList)

Returns the pointer type returned by the GEP instruction, which may be a vector of pointers.

Module * getParent()

Get the module that this global value is contained inside of...

static bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)

Return result of LHS Pred RHS comparison.

bool isEquality() const

Return true if this predicate is either EQ or NE.

bool isAssociative() const LLVM_READONLY

Return true if the instruction is associative:

bool isCommutative() const LLVM_READONLY

Return true if the instruction is commutative:

Class to represent integer types.

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

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

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

static PoisonValue * get(Type *T)

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

void reserve(size_type N)

void push_back(const T &Elt)

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

Class to represent struct types.

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

const fltSemantics & getFltSemantics() const

bool isVectorTy() const

True if this is an instance of VectorType.

bool isIntOrIntVectorTy() const

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

bool isPointerTy() const

True if this is an instance of PointerType.

static IntegerType * getInt1Ty(LLVMContext &C)

bool isEmptyTy() const

Return true if this type is empty, that is, it has no elements or all of its elements are empty.

bool isPPC_FP128Ty() const

Return true if this is powerpc long double.

unsigned getScalarSizeInBits() const LLVM_READONLY

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

bool isFirstClassType() const

Return true if the type is "first class", meaning it is a valid type for a Value.

bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const

Return true if it makes sense to take the size of this type.

LLVMContext & getContext() const

Return the LLVMContext in which this type was uniqued.

bool isX86_AMXTy() const

Return true if this is X86 AMX.

static IntegerType * getInt32Ty(LLVMContext &C)

static IntegerType * getInt64Ty(LLVMContext &C)

bool isIntegerTy() const

True if this is an instance of IntegerType.

bool isFPOrFPVectorTy() const

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

Type * getScalarType() const

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

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

Align getPointerAlignment(const DataLayout &DL) const

Returns an alignment of the pointer value.

LLVMContext & getContext() const

All values hold a context through their type.

Base class of all SIMD vector types.

Type * getElementType() const

#define llvm_unreachable(msg)

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

@ C

The default llvm calling convention, compatible with C.

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

cstfp_pred_ty< is_neg_zero_fp > m_NegZeroFP()

Match a floating-point negative zero.

apint_match m_APInt(const APInt *&Res)

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

auto m_Undef()

Match an arbitrary undef constant.

is_zero m_Zero()

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

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

Combine two pattern matchers matching L || R.

This is an optimization pass for GlobalISel generic memory operations.

bool all_of(R &&range, UnaryPredicate P)

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

Constant * ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2)

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

Constant * ConstantFoldCompareInstruction(CmpInst::Predicate Predicate, Constant *C1, Constant *C2)

Constant * ConstantFoldUnaryInstruction(unsigned Opcode, Constant *V)

Constant * ConstantFoldGetElementPtr(Type *Ty, Constant *C, std::optional< ConstantRange > InRange, ArrayRef< Value * > Idxs)

Constant * ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef< unsigned > Idxs)

Attempt to constant fold an extractvalue instruction with the specified operands and indices.

bool NullPointerIsDefined(const Function *F, unsigned AS=0)

Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...

Constant * ConstantFoldInsertElementInstruction(Constant *Val, Constant *Elt, Constant *Idx)

Attempt to constant fold an insertelement instruction with the specified operands and indices.

constexpr int PoisonMaskElem

Constant * ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx)

Attempt to constant fold an extractelement instruction with the specified operands and indices.

constexpr unsigned BitWidth

APFloat neg(APFloat X)

Returns the negated value of the argument.

Constant * ConstantFoldCastInstruction(unsigned opcode, Constant *V, Type *DestTy)

Constant * ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, ArrayRef< unsigned > Idxs)

ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue instruction with the spe...

unsigned Log2(Align A)

Returns the log2 of the alignment.

Constant * ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2, ArrayRef< int > Mask)

Attempt to constant fold a shufflevector instruction with the specified operands and mask.

Constant * ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2)

This struct is a compact representation of a valid (non-zero power of two) alignment.