LLVM: lib/Transforms/InstCombine/InstCombineSelect.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
45#include
46#include
47#include
48
49#define DEBUG_TYPE "instcombine"
51
52using namespace llvm;
54
55namespace llvm {
57}
58
59
60
64
69 return nullptr;
70
71 bool IsEq;
75 IsEq = true;
77 IsEq = false;
78 else
79 return nullptr;
80
81
84 return nullptr;
85
86
87
90 if (IdC != C) {
92 return nullptr;
94 return nullptr;
95 }
96
97
100 return nullptr;
102 return nullptr;
103
104
105
110 return nullptr;
111
112
113
114
115
117}
118
119
120
121
122
123
124
125
126
127
130 bool CreateAnd,
132 const APInt *SelTC, *SelFC;
134 return nullptr;
135
137
138
139
140
141 const APInt &TC = *SelTC;
142 const APInt &FC = *SelFC;
143 if (!TC.isZero() && !FC.isZero()) {
145 return nullptr;
146
147
148 if (CreateAnd && !CondVal->hasOneUse())
149 return nullptr;
150
151
152
153
154
155 Constant *TCC = ConstantInt::get(SelType, TC);
156 Constant *FCC = ConstantInt::get(SelType, FC);
157 Constant *MaskC = ConstantInt::get(SelType, AndMask);
158 for (auto Opc : {Instruction::Or, Instruction::Xor, Instruction::Add,
159 Instruction::Sub}) {
161 FCC) {
162 if (CreateAnd)
163 V = Builder.CreateAnd(V, MaskC);
164 return Builder.CreateBinOp(Opc, TCC, V);
165 }
166 }
167
168 return nullptr;
169 }
170
171
172 if (!TC.isPowerOf2() && !FC.isPowerOf2())
173 return nullptr;
174
175
176
177 const APInt &ValC = !TC.isZero() ? TC : FC;
178 unsigned ValZeros = ValC.logBase2();
179 unsigned AndZeros = AndMask.logBase2();
180 bool ShouldNotVal = !TC.isZero();
181 bool NeedShift = ValZeros != AndZeros;
182 bool NeedZExtTrunc =
184
185
186
187
188 if (CreateAnd + ShouldNotVal + NeedShift + NeedZExtTrunc >
190 return nullptr;
191
192
193 if (CreateAnd)
194 V = Builder.CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
195
196
197
198 if (ValZeros > AndZeros) {
199 V = Builder.CreateZExtOrTrunc(V, SelType);
200 V = Builder.CreateShl(V, ValZeros - AndZeros);
201 } else if (ValZeros < AndZeros) {
202 V = Builder.CreateLShr(V, AndZeros - ValZeros);
203 V = Builder.CreateZExtOrTrunc(V, SelType);
204 } else {
205 V = Builder.CreateZExtOrTrunc(V, SelType);
206 }
207
208
209
210 if (ShouldNotVal)
211 V = Builder.CreateXor(V, ValC);
212
213 return V;
214}
215
216
217
218
219
220
221
222
223
224
225
227 switch (I->getOpcode()) {
228 case Instruction::Add:
229 case Instruction::FAdd:
230 case Instruction::Mul:
231 case Instruction::FMul:
232 case Instruction::And:
233 case Instruction::Or:
234 case Instruction::Xor:
235 return 3;
236 case Instruction::Sub:
237 case Instruction::FSub:
238 case Instruction::FDiv:
239 case Instruction::Shl:
240 case Instruction::LShr:
241 case Instruction::AShr:
242 return 1;
243 default:
244 return 0;
245 }
246}
247
248
251
252
253
254
259 return nullptr;
260
261
263 Type *CondTy = Cond->getType();
267 return nullptr;
268
269
270
273 CondVTy->getElementCount() !=
275 return nullptr;
276
277
278
279
280
281
282
283
284
285 if (TI->getOpcode() != Instruction::BitCast &&
287 return nullptr;
289
290
291
292 return nullptr;
293 }
294
295
298 SI.getName() + ".v", &SI);
301 }
302
303 Value *OtherOpT, *OtherOpF;
304 bool MatchIsOpZero;
306 bool Swapped = false) -> Value * {
307 assert(!(Commute && Swapped) &&
308 "Commute and Swapped can't set at the same time");
309 if (!Swapped) {
313 MatchIsOpZero = true;
318 MatchIsOpZero = false;
320 }
321 }
322
323 if (!Commute && !Swapped)
324 return nullptr;
325
326
327
328
332 MatchIsOpZero = true;
337 MatchIsOpZero = false;
339 }
340 return nullptr;
341 };
342
344
347
348
351 FMF |= SI.getFastMathFlags();
355 NewSelI->setFastMathFlags(FMF);
356 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
358 return NewFNeg;
359 }
360
361
362
363
364
367 if (TII && FII && TII->getIntrinsicID() == FII->getIntrinsicID()) {
369 if (Value *MatchOp = getCommonOp(TI, FI, true)) {
371 Builder.CreateSelect(Cond, OtherOpT, OtherOpF, "minmaxop", &SI);
373 }
374 }
375
376
377
378
379
380
381 if (TII->getIntrinsicID() == Intrinsic::ldexp) {
382 Value *LdexpVal0 = TII->getArgOperand(0);
383 Value *LdexpExp0 = TII->getArgOperand(1);
384 Value *LdexpVal1 = FII->getArgOperand(0);
385 Value *LdexpExp1 = FII->getArgOperand(1);
391
392 Value *SelectVal = Builder.CreateSelect(Cond, LdexpVal0, LdexpVal1);
393 Value *SelectExp = Builder.CreateSelect(Cond, LdexpExp0, LdexpExp1);
394
396 TII->getType(), Intrinsic::ldexp, {SelectVal, SelectExp});
399 }
400 }
401 }
402
403 auto CreateCmpSel = [&](std::optional P,
404 bool Swapped) -> CmpInst * {
405 if ()
406 return nullptr;
409 if (!MatchOp)
410 return nullptr;
411 Value *NewSel = Builder.CreateSelect(Cond, OtherOpT, OtherOpF,
412 SI.getName() + ".v", &SI);
413 return new ICmpInst(MatchIsOpZero ? *P
415 MatchOp, NewSel);
416 };
417
418
419
423 if (auto *R =
425 return R;
426 if (auto *R =
429 true))
430 return R;
431 }
432 }
433
434
435
436
437
442 return nullptr;
443
444
446 if (!MatchOp)
447 return nullptr;
448
449
450
451
454 return nullptr;
455
456
457
458
459
460
461
464
465
466 if (BO->getOpcode() == Instruction::SDiv ||
467 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)
469 }
470
471
472 Value *NewSI = Builder.CreateSelect(Cond, OtherOpT, OtherOpF,
473 SI.getName() + ".v", &SI);
474 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
475 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
480 return NewBO;
481 }
484 Type *ElementType = TGEP->getSourceElementType();
486 ElementType, Op0, Op1, TGEP->getNoWrapFlags() & FGEP->getNoWrapFlags());
487 }
489 return nullptr;
490}
491
493 if (!C1I.isZero() && !C2I.isZero())
494 return false;
496}
497
498
499
501 Value *FalseVal) {
502
503
508 if (!TVI || !TVI->hasOneUse() || isa(FalseVal))
509 return nullptr;
510
512 unsigned OpToFold = 0;
513 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
514 OpToFold = 1;
515 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
516 OpToFold = 2;
517
518 if (!OpToFold)
519 return nullptr;
520
523 FMF = SI.getFastMathFlags();
525 TVI->getOpcode(), TVI->getType(), true, FMF.noSignedZeros());
526 Value *OOp = TVI->getOperand(2 - OpToFold);
527
528
529 const APInt *OOpC;
532 (!OOpIsAPInt || (C->getUniqueInteger(), *OOpC)))
533 return nullptr;
534
535
536
537
538
539
540
543 return nullptr;
544
545 Value *NewSel = Builder.CreateSelect(SI.getCondition(), Swapped ? C : OOp,
546 Swapped ? OOp : C, "", &SI);
549
550
551
552
553
554
555 NewSelFMF.setNoInfs(TVI->hasNoInfs() ||
558 }
564
567
568
570 }
571 return BO;
572 };
573
574 if (Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal, false))
575 return R;
576
577 if (Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal, true))
578 return R;
579
580 return nullptr;
581}
582
583
584
585
590 const Value *CmpLHS = Cmp->getOperand(0);
591 const Value *CmpRHS = Cmp->getOperand(1);
593
594
595
596
597
598 if (CmpRHS == TVal) {
601 }
602
603
604
606 return nullptr;
607
611 return Builder.CreateBinaryIntrinsic(Intrinsic::smax, TVal, FVal);
612 }
613
617 return Builder.CreateBinaryIntrinsic(Intrinsic::smin, TVal, FVal);
618 }
619
623 return Builder.CreateBinaryIntrinsic(Intrinsic::umax, TVal, FVal);
624 }
625
626
627
633 return Builder.CreateBinaryIntrinsic(Intrinsic::umin, TVal, FVal);
634 }
635
636 return nullptr;
637}
638
639
640
641
642
643
644
645
646
650 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
653 return nullptr;
654
655
658 return nullptr;
659
660
663
664
665
666
667 if (HasShift &&
671 return nullptr;
672
673 if (!HasShift)
675
678 return nullptr;
679
680
681
682 Constant *One = ConstantInt::get(SelType, 1);
683 Value *MaskB = HasShift ? Builder.CreateShl(One, Z) : One;
684 Value *FullMask = Builder.CreateOr(Y, MaskB);
685 Value *MaskedX = Builder.CreateAnd(X, FullMask);
686 Value *ICmpNeZero = Builder.CreateIsNotNull(MaskedX);
687 return new ZExtInst(ICmpNeZero, SelType);
688}
689
690
691
692
693
694
701 return nullptr;
702
706 }
707
709 const APInt *C2, *C1;
713 return nullptr;
714
717 return nullptr;
718
720 if (!FI)
721 return nullptr;
722
723 FI->setHasNoSignedWrap(false);
724 FI->setHasNoUnsignedWrap(false);
725 return FVal;
726}
727
728
729
730
731
732
740 return nullptr;
741
750 return nullptr;
751
752
755
760
761 bool IsExact = Ashr->isExact() && cast(TrueVal)->isExact();
762 return Builder.CreateAShr(X, Y, IC->getName(), IsExact);
763 }
764
765 return nullptr;
766}
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
790 const APInt &AndMask, bool CreateAnd,
792
793 if (!TrueVal->getType()->isIntOrIntVectorTy())
794 return nullptr;
795
796 unsigned C1Log = AndMask.logBase2();
800 bool NeedXor;
802 Y = TrueVal;
804 NeedXor = false;
806 Y = FalseVal;
808 NeedXor = true;
809 } else {
810 return nullptr;
811 }
812
813
814 auto *IdentityC =
816 true);
817 if (IdentityC == nullptr || !IdentityC->isNullValue())
818 return nullptr;
819
820 unsigned C2Log = C2->logBase2();
821
822 bool NeedShift = C1Log != C2Log;
823 bool NeedZExtTrunc = Y->getType()->getScalarSizeInBits() !=
824 V->getType()->getScalarSizeInBits();
825
826
827 if ((NeedShift + NeedXor + NeedZExtTrunc + CreateAnd) >
829 return nullptr;
830
831 if (CreateAnd) {
832
833 V = Builder.CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
834 }
835
836 if (C2Log > C1Log) {
837 V = Builder.CreateZExtOrTrunc(V, Y->getType());
838 V = Builder.CreateShl(V, C2Log - C1Log);
839 } else if (C1Log > C2Log) {
840 V = Builder.CreateLShr(V, C1Log - C2Log);
841 V = Builder.CreateZExtOrTrunc(V, Y->getType());
842 } else
843 V = Builder.CreateZExtOrTrunc(V, Y->getType());
844
845 if (NeedXor)
846 V = Builder.CreateXor(V, *C2);
847
848 auto *Res = Builder.CreateBinOp(BinOp->getOpcode(), Y, V);
850 BO->copyIRFlags(BinOp);
851 return Res;
852}
853
854
855
864
865
869 Constant *OrC = ConstantInt::get(Ty, *C);
870 Value *NewSel = Builder.CreateSelect(Cond, Zero, OrC, "masksel", &Sel);
871 return BinaryOperator::CreateOr(T, NewSel);
872 }
873
874
878 Constant *OrC = ConstantInt::get(Ty, *C);
879 Value *NewSel = Builder.CreateSelect(Cond, OrC, Zero, "masksel", &Sel);
880 return BinaryOperator::CreateOr(F, NewSel);
881 }
882
883 return nullptr;
884}
885
886
887
888
889
890
891
892
893
894
895
896
897
898
901 auto *CondVal = SI.getCondition();
902 auto *TrueVal = SI.getTrueValue();
903 auto *FalseVal = SI.getFalseValue();
906
907
908
909
912 return nullptr;
913
916
917
918
919
920
923 return nullptr;
924
925 bool FreezeY;
932 FreezeY = true;
935 FreezeY = false;
936 } else {
937 return nullptr;
938 }
939
942
943
944
946 return nullptr;
947
949 if (FreezeY) {
953 FalseValI->getOperand(0) == Y
954 ? 0
955 : (FalseValI->getOperand(1) == Y ? 1 : 2),
956 FrY);
957 }
959}
960
961
962
964 const Value *TrueVal,
965 const Value *FalseVal,
970
971
972
976 }
977
979 return nullptr;
980
981
982
985 return Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, A,
986 ConstantInt::get(A->getType(), 1));
987 return nullptr;
988 }
989
991 return nullptr;
992
994
997 }
998
1000 "Unexpected isUnsigned predicate!");
1001
1002
1003
1004
1005
1006 bool IsNegative = false;
1011 IsNegative = true;
1015 return nullptr;
1016
1017
1018
1019 if (IsNegative && !TrueVal->hasOneUse() && !ICI->hasOneUse())
1020 return nullptr;
1021
1022
1023
1024 Value *Result = Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, A, B);
1025 if (IsNegative)
1026 Result = Builder.CreateNeg(Result);
1027 return Result;
1028}
1029
1033
1034
1035 Value *Cmp0 = Cmp->getOperand(0);
1036 Value *Cmp1 = Cmp->getOperand(1);
1040
1041
1042
1043
1047 }
1049 return nullptr;
1050
1051
1052
1056 return Builder.CreateBinaryIntrinsic(
1057 Intrinsic::uadd_sat, Cmp0, ConstantInt::get(Cmp0->getType(), 1));
1058 }
1059 return nullptr;
1060 }
1061
1065
1066
1067 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1068 ConstantInt::get(Cmp0->getType(), *C));
1069 }
1070
1071
1072
1076
1077 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1078 ConstantInt::get(Cmp0->getType(), *C));
1079 }
1080
1081
1082
1086
1087 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1088 ConstantInt::get(Cmp0->getType(), *C));
1089 }
1090
1091
1095 }
1097 return nullptr;
1098
1099
1100
1104
1105
1106 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, X, Y);
1107 }
1108
1109
1110 X = Cmp0;
1111 Y = Cmp1;
1113
1114
1116 return Builder.CreateBinaryIntrinsic(
1118 }
1119
1120
1124
1125
1126 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp1, Y);
1127 }
1128
1129 return nullptr;
1130}
1131
1135
1136 Value *Cmp0 = Cmp->getOperand(0);
1137 Value *Cmp1 = Cmp->getOperand(1);
1141
1142
1146 }
1147
1149 return nullptr;
1150
1151
1152
1153
1156 return Builder.CreateBinaryIntrinsic(
1157 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->getType(), 1));
1158 }
1159 return nullptr;
1160 }
1161
1162
1163
1164
1170
1171
1175 Pred = Flipped->first;
1176 Cmp1 = Flipped->second;
1177 }
1178 }
1179
1180
1184 return Builder.CreateBinaryIntrinsic(
1185 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->getType(), *C));
1186 }
1187
1188
1192 }
1193
1195 return nullptr;
1196
1199
1200
1201 return Builder.CreateBinaryIntrinsic(Intrinsic::sadd_sat, X, Cmp1);
1202 }
1203
1204 return nullptr;
1205}
1206
1209 if (!Cmp->hasOneUse())
1210 return nullptr;
1211
1213 return V;
1214
1216 return V;
1217
1218 return nullptr;
1219}
1220
1221
1226 if (!TI || !FI)
1227 return nullptr;
1228
1229
1231 Value *A = Cmp->getOperand(0);
1232 Value *B = Cmp->getOperand(1);
1233
1234
1238 }
1239
1240
1241
1245 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
1246 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
1247
1248
1249
1250
1251
1252
1253 TI->setHasNoUnsignedWrap(false);
1254 if (!TI->hasNoSignedWrap())
1255 TI->setHasNoSignedWrap(TI->hasOneUse());
1256 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI, Builder.getTrue());
1257 }
1258
1259
1263 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
1264 Builder.getFalse());
1265 }
1266
1267
1271 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,
1272 Builder.getFalse());
1273 }
1274
1275
1279 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,
1280 Builder.getFalse());
1281 }
1282
1283
1287 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
1288 Builder.getFalse());
1289 }
1290
1291 return nullptr;
1292}
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1305 Value *FalseVal,
1307 unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits();
1309 return nullptr;
1310
1313
1315 if ((FalseVal,
1317 return nullptr;
1318
1320 return nullptr;
1321
1323 return nullptr;
1324
1328 return nullptr;
1329
1331 II->getModule(), Intrinsic::cttz, II->getType());
1333}
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1352
1353
1355 return nullptr;
1356
1360 std::swap(SelectArg, ValueOnZero);
1361
1362
1366 Count = SelectArg;
1367
1368
1369
1373 return nullptr;
1374
1375
1376
1377
1378 if ((X != CmpLHS || (CmpRHS, m_Zero())) &&
1381 return nullptr;
1382
1384
1385
1386
1387 unsigned SizeOfInBits = Count->getType()->getScalarSizeInBits();
1389
1390
1392
1393 II->dropPoisonGeneratingAnnotations();
1395 return SelectArg;
1396 }
1397
1398
1399
1400
1401 if (II->hasOneUse() && SelectArg->hasOneUse() &&
1404
1405 II->dropUBImplyingAttrsAndMetadata();
1407 }
1408
1409 return nullptr;
1410}
1411
1415
1416 if (->getType()->isIntOrIntVectorTy())
1417 return nullptr;
1418
1424 return nullptr;
1425
1426
1430 ConstantInt::get(Type::getInt1Ty(Cmp.getContext()), IntMinIsPoison);
1433
1435 return IC.Builder.CreateNeg(Abs);
1436 return Abs;
1437 }
1438
1442 }
1443
1444 return nullptr;
1445}
1446
1448 unsigned Depth) {
1449
1451 return false;
1452
1454
1456 if ( ||
->hasOneUse() ||
1458 return false;
1459
1460
1462 return false;
1463
1465 for (Use &U : I->operands()) {
1466 if (U == Old) {
1470 } else {
1472 }
1473 }
1475}
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1495
1496
1498 bool Swapped = false;
1499 if (Cmp.isEquivalence(true)) {
1501 Swapped = true;
1502 } else if (.isEquivalence()) {
1503 return nullptr;
1504 }
1505
1506 Value *CmpLHS = Cmp.getOperand(0), *CmpRHS = Cmp.getOperand(1);
1507 auto ReplaceOldOpWithNewOp = [&](Value *OldOp,
1508 Value *NewOp) -> Instruction * {
1509
1510
1511
1512
1513
1514
1516 return nullptr;
1517
1519 true)) {
1520
1521
1522
1526
1527
1528
1529
1530
1536 return nullptr;
1537 }
1538 }
1539
1540
1541
1542
1543
1544
1545
1550 return &Sel;
1551 return nullptr;
1552 };
1553
1555 if (CanReplaceCmpLHSWithRHS) {
1556 if (Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1557 return R;
1558 }
1560 if (CanReplaceCmpRHSWithLHS) {
1561 if (Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1562 return R;
1563 }
1564
1566 if (!FalseInst)
1567 return nullptr;
1568
1569
1570
1571
1572
1573
1574
1575
1576
1578 if ((CanReplaceCmpLHSWithRHS &&
1580 false,
1581 &DropFlags) == TrueVal) ||
1582 (CanReplaceCmpRHSWithLHS &&
1584 false,
1585 &DropFlags) == TrueVal)) {
1586 for (Instruction *I : DropFlags) {
1587 I->dropPoisonGeneratingAnnotations();
1589 }
1590
1592 }
1593
1594 return nullptr;
1595}
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1612
1614 return nullptr;
1615
1616 if ((YeqZ,
1619
1620 if ((YeqZ,
1622 return nullptr;
1623
1626 return nullptr;
1627
1628 if ((XeqY,
1630 return nullptr;
1631
1634}
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1655
1656
1657
1659 return nullptr;
1665 return nullptr;
1666
1670 }
1671
1672
1673
1674 switch (Pred0) {
1677
1678
1679
1683 return nullptr;
1684 break;
1687
1688
1693 return nullptr;
1696 break;
1697 default:
1698 return nullptr;
1699 }
1700
1701
1702
1704 return nullptr;
1705
1706
1707
1708 if (Cmp00->getType() != X->getType() && X->hasOneUse())
1710
1711
1712
1714 if (Cmp00 == X)
1716 else if ((Cmp00,
1719 return nullptr;
1720
1724 Value *ReplacementLow, *ReplacementHigh;
1726 m_Value(ReplacementHigh))) ||
1730 return nullptr;
1731
1733 return nullptr;
1734
1735
1736
1737
1738
1739 switch (Pred1) {
1741 break;
1743
1744
1745
1746 return nullptr;
1748
1749
1754 return nullptr;
1756 [[fallthrough]];
1758
1759
1761 std::swap(ReplacementLow, ReplacementHigh);
1762 break;
1763 default:
1764 return nullptr;
1765 }
1767 "Unexpected predicate type.");
1768
1769
1772
1775 "Unexpected predicate type.");
1777 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1778
1779
1782 if (!Precond1 || (Precond1, m_One()))
1783 return nullptr;
1784
1787 if (!Precond2 || (Precond2, m_One()))
1788 return nullptr;
1789
1790
1791
1792
1793 if (X->getType() != Sel0.getType()) {
1797 return nullptr;
1799 ReplacementLow =
1801 ReplacementHigh =
1803 assert(ReplacementLow && ReplacementHigh &&
1804 "Constant folding of ImmConstant cannot fail");
1805 }
1806
1807
1810 Value *MaybeReplacedLow =
1811 Builder.CreateSelect(ShouldReplaceLow, ReplacementLow, X);
1812
1813
1814
1816 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1818}
1819
1820
1821
1822
1823
1824
1825
1826
1827
1829tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,
1837 return nullptr;
1838
1839
1841 return nullptr;
1842
1843
1844
1846 return nullptr;
1847
1848
1849
1851 return nullptr;
1852
1853
1854
1855
1857 return nullptr;
1858
1859
1860 Value *SelVal0, *SelVal1;
1862
1863
1866 return nullptr;
1867
1868
1869 auto MatchesSelectValue = [SelVal0, SelVal1](Constant *C) {
1870 return C->isElementWiseEqual(SelVal0) || C->isElementWiseEqual(SelVal1);
1871 };
1872
1873
1874 if (MatchesSelectValue(C0))
1875 return nullptr;
1876
1877
1879 if (!FlippedStrictness)
1880 return nullptr;
1881
1882
1883 if (!MatchesSelectValue(FlippedStrictness->second))
1884 return nullptr;
1885
1886
1889
1892 Cmp.getName() + ".inv");
1896
1897 return &Sel;
1898}
1899
1903 if (->hasOneUse())
1904 return nullptr;
1905
1906 const APInt *CmpC;
1908 return nullptr;
1909
1910
1915
1916
1920
1921 return nullptr;
1922}
1923
1926 const APInt *CmpC;
1930 return nullptr;
1931
1932
1933 Value *TVal = SI.getTrueValue();
1934 Value *FVal = SI.getFalseValue();
1936
1939
1942
1945
1948 }
1949
1950
1951
1959 else
1960 return nullptr;
1961
1963 const APInt *OpC;
1967 if (R == *C) {
1968 Op->dropPoisonGeneratingFlags();
1969 return Op;
1970 }
1971 }
1973 MMI && MMI->getLHS() == V && match(MMI->getRHS(), m_APInt(OpC))) {
1975 {InvDomCR, ConstantRange(*OpC)});
1976 if (R == *C) {
1977 MMI->dropPoisonGeneratingAnnotations();
1978 return MMI;
1979 }
1980 }
1981
1982 return nullptr;
1983}
1984
1985
1986
1989 Value *FalseVal) {
1991
1993 return nullptr;
1994
1997
1999 return nullptr;
2000
2004 return nullptr;
2005
2008
2015 } else {
2016 return nullptr;
2017 }
2018
2020 return nullptr;
2021
2022 return new ICmpInst(Pred, CmpLHS, B);
2023}
2024
2029 return nullptr;
2030
2035
2038
2040 foldSelectWithExtremeEqCond(CmpLHS, CmpRHS, TrueVal, FalseVal))
2041 return Res;
2042
2043 return nullptr;
2044}
2045
2046
2047
2050 Value *FalseVal) {
2054
2056 return nullptr;
2057
2059 return nullptr;
2060
2064 }
2065
2067 return nullptr;
2068
2069 bool IsIntrinsic;
2070 unsigned Opcode;
2072 Opcode = BOp->getOpcode();
2073 IsIntrinsic = false;
2074
2075
2076
2077
2079 return nullptr;
2080
2082 return nullptr;
2083
2086 return nullptr;
2087 Opcode = II->getIntrinsicID();
2088 IsIntrinsic = true;
2089 } else {
2090 return nullptr;
2091 }
2092
2095 const DataLayout &DL = Cmp->getDataLayout();
2097
2102 };
2103
2104 if (C3 == FoldBinaryOpOrIntrinsic(C1, C2)) {
2106 RHS = C1;
2107 } else if (Flipped && C3 == FoldBinaryOpOrIntrinsic(Flipped->second, C2)) {
2109 RHS = Flipped->second;
2110 } else {
2111 return nullptr;
2112 }
2113
2115 Value *MinMax = Builder.CreateBinaryIntrinsic(MinMaxID, X, RHS);
2116 if (IsIntrinsic)
2117 return Builder.CreateBinaryIntrinsic(Opcode, MinMax, C2);
2118
2120 Value *BinOp = Builder.CreateBinOp(BinOpc, MinMax, C2);
2121
2122
2123
2125 if (BinOpc == Instruction::Add || BinOpc == Instruction::Sub ||
2126 BinOpc == Instruction::Mul) {
2129 willNotOverflow(BinOpc, RHS, C2, *BinOpInst, true))
2130 BinOpInst->setHasNoSignedWrap();
2132 willNotOverflow(BinOpc, RHS, C2, *BinOpInst, false))
2133 BinOpInst->setHasNoUnsignedWrap();
2134 }
2135 }
2136 return BinOp;
2137}
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(
2153 if (.hasOneUse() || !ICI->hasOneUse())
2154 return nullptr;
2157 const APInt *Constant1, *Constant2;
2158 if ((SI.getCondition(),
2165 return nullptr;
2166
2173 return nullptr;
2174
2175 auto *Ty = A->getType();
2178
2179
2181 return nullptr;
2182
2183 APInt AdjAP1 = *Constant1 - MostSignificantBit + 1;
2184 APInt AdjAP2 = *Constant2 - MostSignificantBit + 1;
2185
2186 auto *Adj1 = ConstantInt::get(Ty, AdjAP1);
2187 auto *Adj2 = ConstantInt::get(Ty, AdjAP2);
2188
2192 Constant *MSBConst = ConstantInt::get(Ty, MostSignificantBit);
2193 return BinaryOperator::CreateAnd(Or, MSBConst);
2194}
2195
2196
2200 canonicalizeSPF(*ICI, SI.getTrueValue(), SI.getFalseValue(), *this))
2202
2203 if (Value *V = foldSelectInstWithICmpConst(SI, ICI, Builder))
2205
2206 if (Value *V = canonicalizeClampLike(SI, *ICI, Builder, *this))
2208
2209 if (Instruction *NewSel =
2210 tryToReuseConstantFromSelectInComparison(SI, *ICI, *this))
2211 return NewSel;
2212 if (Instruction *Folded =
2213 foldICmpUSubSatWithAndForMostSignificantBitCmp(SI, ICI, Builder))
2214 return Folded;
2215
2216
2223
2224 if (Instruction *NewSel = foldSelectICmpEq(SI, ICI, *this))
2225 return NewSel;
2226
2227
2228
2229
2230
2234 InstCombiner::BuilderTy::InsertPointGuard Guard(Builder);
2235 Builder.SetInsertPoint(&SI);
2238 SI.swapValues();
2239 SI.swapProfMetadata();
2240 return &SI;
2241 }
2242
2245
2246 if (Instruction *V =
2248 return V;
2249
2252
2253 if (Instruction *V = foldSelectCtlzToCttz(ICI, TrueVal, FalseVal, Builder))
2254 return V;
2255
2256 if (Instruction *V = foldSelectZeroOrOnes(ICI, TrueVal, FalseVal, Builder))
2257 return V;
2258
2261
2262 if (Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *this))
2264
2267
2270
2273
2276
2278}
2279
2280
2281
2288 return nullptr;
2289
2291
2292
2293
2296 }
2297
2298 return nullptr;
2299}
2300
2301
2302
2305 Value *CondVal = SI.getCondition();
2310 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
2311 return nullptr;
2312
2313 Instruction *AddOp = nullptr, *SubOp = nullptr;
2314 if ((TI->getOpcode() == Instruction::Sub &&
2315 FI->getOpcode() == Instruction::Add) ||
2316 (TI->getOpcode() == Instruction::FSub &&
2317 FI->getOpcode() == Instruction::FAdd)) {
2318 AddOp = FI;
2319 SubOp = TI;
2320 } else if ((FI->getOpcode() == Instruction::Sub &&
2321 TI->getOpcode() == Instruction::Add) ||
2322 (FI->getOpcode() == Instruction::FSub &&
2323 TI->getOpcode() == Instruction::FAdd)) {
2324 AddOp = TI;
2325 SubOp = FI;
2326 }
2327
2328 if (AddOp) {
2329 Value *OtherAddOp = nullptr;
2330 if (SubOp->getOperand(0) == AddOp->getOperand(0)) {
2332 } else if (SubOp->getOperand(0) == AddOp->getOperand(1)) {
2334 }
2335
2336 if (OtherAddOp) {
2337
2338
2339 Value *NegVal;
2340 if (SI.getType()->isFPOrFPVectorTy()) {
2341 NegVal = Builder.CreateFNeg(SubOp->getOperand(1));
2344 Flags &= SubOp->getFastMathFlags();
2345 NegInst->setFastMathFlags(Flags);
2346 }
2347 } else {
2348 NegVal = Builder.CreateNeg(SubOp->getOperand(1));
2349 }
2350
2351 Value *NewTrueOp = OtherAddOp;
2352 Value *NewFalseOp = NegVal;
2353 if (AddOp != TI)
2354 std::swap(NewTrueOp, NewFalseOp);
2355 Value *NewSel = Builder.CreateSelect(CondVal, NewTrueOp, NewFalseOp,
2356 SI.getName() + ".p", &SI);
2357
2358 if (SI.getType()->isFPOrFPVectorTy()) {
2360 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
2361
2363 Flags &= SubOp->getFastMathFlags();
2365 return RI;
2366 } else
2367 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
2368 }
2369 }
2370 return nullptr;
2371}
2372
2373
2374
2375
2376
2377
2380 Value *CondVal = SI.getCondition();
2383
2387 return nullptr;
2388
2391
2392 auto IsSignedSaturateLimit = [&](Value *Limit, bool IsAdd) {
2394
2400 return false;
2401
2402 auto IsZeroOrOne = [](const APInt &C) { return C.isZero() || C.isOne(); };
2408 };
2409
2411 return false;
2412
2413 if (IsAdd) {
2414
2415
2416
2417
2419 IsMinMax(TrueVal, FalseVal))
2420 return true;
2421
2422
2423
2424
2426 IsMinMax(FalseVal, TrueVal))
2427 return true;
2428 } else {
2429
2430
2432 IsMinMax(TrueVal, FalseVal))
2433 return true;
2434
2435
2437 IsMinMax(FalseVal, TrueVal))
2438 return true;
2439
2440
2442 IsMinMax(FalseVal, TrueVal))
2443 return true;
2444
2445
2447 IsMinMax(TrueVal, FalseVal))
2448 return true;
2449 }
2450
2451 return false;
2452 };
2453
2455 if (II->getIntrinsicID() == Intrinsic::uadd_with_overflow &&
2457
2458 NewIntrinsicID = Intrinsic::uadd_sat;
2459 else if (II->getIntrinsicID() == Intrinsic::usub_with_overflow &&
2461
2462 NewIntrinsicID = Intrinsic::usub_sat;
2463 else if (II->getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2464 IsSignedSaturateLimit(TrueVal, true))
2465
2466
2467
2468
2469
2470
2471
2472
2473 NewIntrinsicID = Intrinsic::sadd_sat;
2474 else if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2475 IsSignedSaturateLimit(TrueVal, false))
2476
2477
2478
2479
2480
2481
2482
2483
2484 NewIntrinsicID = Intrinsic::ssub_sat;
2485 else
2486 return nullptr;
2487
2489 NewIntrinsicID, SI.getType());
2491}
2492
2497 return nullptr;
2498
2502 return nullptr;
2503
2504 auto ExtOpcode = ExtInst->getOpcode();
2505 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2506 return nullptr;
2507
2508
2509
2515 (!Cmp || Cmp->getOperand(0)->getType() != SmallType))
2516 return nullptr;
2517
2518
2519
2522 if (TruncC && ExtInst->hasOneUse()) {
2526
2527
2528
2529 Value *NewSel = Builder.CreateSelect(Cond, X, TruncCVal, "narrow", &Sel);
2531 }
2532
2533 return nullptr;
2534}
2535
2536
2537
2539 Value *CondVal = SI.getCondition();
2543 return nullptr;
2544
2545 unsigned NumElts = CondValTy->getNumElements();
2547 Mask.reserve(NumElts);
2548 for (unsigned i = 0; i != NumElts; ++i) {
2550 if (!Elt)
2551 return nullptr;
2552
2554
2555 Mask.push_back(i);
2557
2558 Mask.push_back(i + NumElts);
2560
2561
2562
2563 return nullptr;
2564 } else {
2565
2566 return nullptr;
2567 }
2568 }
2569
2571}
2572
2573
2574
2575
2576
2580 if (!Ty)
2581 return nullptr;
2582
2583
2586 return nullptr;
2587
2588
2589
2590
2593}
2594
2595
2596
2597
2603
2607 return nullptr;
2608
2609
2610
2611 if (TVal == A || TVal == B || FVal == A || FVal == B)
2612 return nullptr;
2613
2616 return nullptr;
2617
2618
2619 Value *TSrc, *FSrc;
2622 return nullptr;
2623
2624
2625
2626
2628 if (TSrc == C && FSrc == D) {
2629
2630
2632 } else if (TSrc == D && FSrc == C) {
2633
2634
2636 } else {
2637 return nullptr;
2638 }
2640}
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2666
2667
2668
2669
2672 if (!Extract)
2673 return nullptr;
2674 if (Extract->getIndices()[0] != I)
2675 return nullptr;
2677 };
2678
2679
2680
2681 if (SI.hasOneUse())
2683 if (Select->getCondition() == SI.getCondition())
2684 if (Select->getFalseValue() == SI.getTrueValue() ||
2685 Select->getTrueValue() == SI.getFalseValue())
2686 return nullptr;
2687
2688
2689 auto *CmpXchg = isExtractFromCmpXchg(SI.getCondition(), 1);
2690 if (!CmpXchg)
2691 return nullptr;
2692
2693
2694
2695
2696 if (auto *X = isExtractFromCmpXchg(SI.getTrueValue(), 0))
2697 if (X == CmpXchg && X->getCompareOperand() == SI.getFalseValue())
2698 return SI.getFalseValue();
2699
2700
2701
2702
2703 if (auto *X = isExtractFromCmpXchg(SI.getFalseValue(), 0))
2704 if (X == CmpXchg && X->getCompareOperand() == SI.getTrueValue())
2705 return SI.getFalseValue();
2706
2707 return nullptr;
2708}
2709
2710
2711
2712
2713
2714
2715
2716
2717
2720
2723 return nullptr;
2724
2727 return nullptr;
2728
2729 Value *SV0, *SV1, *SA0, *SA1;
2735 return nullptr;
2736
2737
2738 if (Or0->getOpcode() == BinaryOperator::LShr) {
2742 }
2744 Or1->getOpcode() == BinaryOperator::LShr &&
2745 "Illegal or(shift,shift) pair");
2746
2747
2750 ShAmt = SA0;
2752 ShAmt = SA1;
2753 else
2754 return nullptr;
2755
2756
2757
2758
2759
2760 bool IsFshl = (ShAmt == SA0);
2762 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2763 return nullptr;
2764
2765
2769 return nullptr;
2770
2771
2772
2773 if (SV0 != SV1) {
2778 }
2779
2780
2781
2782 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2787}
2788
2795
2796
2797
2802 return nullptr;
2803
2804 assert(TC != FC && "Expected equal select arms to simplify");
2805
2808 bool IsTrueIfSignSet;
2812 (Pred, *C, IsTrueIfSignSet) || X->getType() != SelType)
2813 return nullptr;
2814
2815
2816
2817
2818
2819
2820
2821 if (IsTrueIfSignSet ^ TC->isNegative())
2823
2824
2825
2826 Value *MagArg = ConstantFP::get(SelType, abs(*TC));
2830}
2831
2834 return nullptr;
2835
2840
2845 I->copyIRFlags(&Sel);
2848 M, Intrinsic::vector_reverse, V->getType());
2850 };
2851
2853
2856 return createSelReverse(C, X, Y);
2857
2858
2860 return createSelReverse(C, X, FVal);
2861 }
2862
2865 return createSelReverse(C, TVal, Y);
2866 }
2867
2869 if (!VecTy)
2870 return nullptr;
2871
2872 unsigned NumElts = VecTy->getNumElements();
2873 APInt PoisonElts(NumElts, 0);
2876 if (V != &Sel)
2878 return &Sel;
2879 }
2880
2881
2882
2883
2884 ArrayRef Mask;
2888 if (X == FVal) {
2889
2891 return new ShuffleVectorInst(X, NewSel, Mask);
2892 }
2893 if (Y == FVal) {
2894
2896 return new ShuffleVectorInst(NewSel, Y, Mask);
2897 }
2898 }
2902 if (X == TVal) {
2903
2905 return new ShuffleVectorInst(X, NewSel, Mask);
2906 }
2907 if (Y == TVal) {
2908
2910 return new ShuffleVectorInst(NewSel, Y, Mask);
2911 }
2912 }
2913
2914 return nullptr;
2915}
2916
2920
2921
2922 auto *IDomNode = DT[BB]->getIDom();
2923 if (!IDomNode)
2924 return nullptr;
2925 BasicBlock *IDom = IDomNode->getBlock();
2926
2928 Value *IfTrue, *IfFalse;
2940 } else
2941 return nullptr;
2942
2943
2944 if (TrueSucc == FalseSucc)
2945 return nullptr;
2946
2947
2948
2949
2950
2951
2956
2962 else
2963 return nullptr;
2964
2966 if (!DT.dominates(Insn, Pred->getTerminator()))
2967 return nullptr;
2968 }
2969
2974 PN->takeName(&Sel);
2975 return PN;
2976}
2977
2980
2985 CandidateBlocks.insert(I->getParent());
2986
2987 for (BasicBlock *BB : CandidateBlocks)
2988 if (auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2989 return PN;
2990 return nullptr;
2991}
2992
2993
2994
2995
2996
2997
2998
3001 Value *CondVal = SI.getCondition();
3004
3006 Value *Op, *RemRes, *Remainder;
3008 bool TrueIfSigned = false;
3009
3012 return nullptr;
3013
3014
3015
3016 if (!TrueIfSigned)
3018
3019 auto FoldToBitwiseAnd = [&](Value *Remainder) -> Instruction * {
3022 return BinaryOperator::CreateAnd(Op, Add);
3023 };
3024
3025
3026
3027
3028
3029
3033 FalseVal == RemRes)
3034 return FoldToBitwiseAnd(Remainder);
3035
3036
3037
3038
3039
3042 FalseVal == RemRes)
3043 return FoldToBitwiseAnd(ConstantInt::get(RemRes->getType(), 2));
3044
3045 return nullptr;
3046}
3047
3048
3049static Value *simplifyNestedSelectsUsingImpliedCond(SelectInst &SI,
3051 bool CondIsTrue,
3053 Value *InnerCondVal = SI.getCondition();
3054 Value *InnerTrueVal = SI.getTrueValue();
3055 Value *InnerFalseVal = SI.getFalseValue();
3057 "The type of inner condition must match with the outer.");
3058 if (auto Implied = isImpliedCondition(CondVal, InnerCondVal, DL, CondIsTrue))
3059 return *Implied ? InnerTrueVal : InnerFalseVal;
3060 return nullptr;
3061}
3062
3063Instruction *InstCombinerImpl::foldAndOrOfSelectUsingImpliedCond(Value *Op,
3065 bool IsAnd) {
3066 assert(Op->getType()->isIntOrIntVectorTy(1) &&
3067 "Op must be either i1 or vector of i1.");
3068 if (SI.getCondition()->getType() != Op->getType())
3069 return nullptr;
3070 if (Value *V = simplifyNestedSelectsUsingImpliedCond(SI, Op, IsAnd, DL))
3071 return createSelectInstWithUnknownProfile(
3074 return nullptr;
3075}
3076
3077
3078
3081 Value *CondVal = SI.getCondition();
3082
3083 bool ChangedFMF = false;
3084 for (bool Swap : {false, true}) {
3086 Value *X = SI.getFalseValue();
3088
3089 if (Swap)
3091
3093 continue;
3094
3095
3096
3097
3098
3099
3108 }
3112 }
3113 }
3114
3116 return nullptr;
3117
3118
3119
3120
3122 if (FMF.noNaNs() && .hasNoNaNs()) {
3123 SI.setHasNoNaNs(true);
3124 ChangedFMF = true;
3125 }
3126 if (FMF.noInfs() && .hasNoInfs()) {
3127 SI.setHasNoInfs(true);
3128 ChangedFMF = true;
3129 }
3130
3131
3134 SI.setHasNoNaNs(true);
3135 ChangedFMF = true;
3136 }
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148 if (.hasNoSignedZeros() &&
3150 return nullptr;
3151 if (.hasNoNaNs() &&
3153 return nullptr;
3154
3155 if (Swap)
3157
3162
3163 if (IsLTOrLE) {
3166 }
3167 if (IsGTOrGE) {
3169 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
3171 return NewFNeg;
3172 }
3173 }
3174
3175
3176
3177
3178 for (bool Swap : {false, true}) {
3180 Value *X = SI.getFalseValue();
3181
3182 if (Swap)
3184
3187 bool TrueIfSigned;
3188 if ((CondVal,
3191 continue;
3193 return nullptr;
3194 if (Swap == TrueIfSigned && !CondVal->hasOneUse() && ->hasOneUse())
3195 return nullptr;
3196
3197
3198
3200 if (Swap != TrueIfSigned)
3203 }
3204
3205 return ChangedFMF ? &SI : nullptr;
3206}
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3223foldRoundUpIntegerWithPow2Alignment(SelectInst &SI,
3226 Value *X = SI.getTrueValue();
3227 Value *XBiasedHighBits = SI.getFalseValue();
3228
3230 Value *XLowBits;
3233 return nullptr;
3234
3237
3238
3239
3240 const APInt *LowBitMaskCst;
3242 return nullptr;
3243
3244
3245 const APInt *BiasCst, *HighBitMaskCst;
3246 if ((XBiasedHighBits,
3249 (XBiasedHighBits,
3252 return nullptr;
3253
3254 if (!LowBitMaskCst->isMask())
3255 return nullptr;
3256
3257 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
3258 if (InvertedLowBitMaskCst != *HighBitMaskCst)
3259 return nullptr;
3260
3261 APInt AlignmentCst = *LowBitMaskCst + 1;
3262
3263 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
3264 return nullptr;
3265
3266 if (!XBiasedHighBits->hasOneUse()) {
3267
3268 if (*BiasCst == *LowBitMaskCst && impliesPoison(XBiasedHighBits, X))
3269 return XBiasedHighBits;
3270 return nullptr;
3271 }
3272
3273
3275 Value *XOffset = Builder.CreateAdd(X, ConstantInt::get(Ty, *LowBitMaskCst),
3276 X->getName() + ".biased");
3277 Value *R = Builder.CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));
3279 return R;
3280}
3281
3282namespace {
3283struct DecomposedSelect {
3287};
3288}
3289
3290
3291
3292
3293
3295foldSelectOfSymmetricSelect(SelectInst &OuterSelVal,
3297
3298 Value *OuterCond, *InnerCond, *InnerTrueVal, *InnerFalseVal;
3300 &OuterSelVal,
3303 m_Value(InnerFalseVal))),
3307 return nullptr;
3308
3310 return nullptr;
3311
3314}
3315
3316
3317
3318
3319
3320
3321
3322
3325
3326 DecomposedSelect OuterSel;
3327 match(&OuterSelVal,
3329 m_Value(OuterSel.FalseVal)));
3330
3331
3333 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
3334
3335
3337 return nullptr;
3338
3339
3341 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
3342
3343
3346 return nullptr;
3347
3348
3349 DecomposedSelect InnerSel;
3350 if ((InnerSelVal,
3352 m_Value(InnerSel.FalseVal))))
3353 return nullptr;
3354
3355
3357 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3358
3359 Value *AltCond = nullptr;
3360 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](auto m_InnerCond) {
3361
3362
3363
3364
3365 return IsAndVariant ? match(OuterSel.Cond,
3369 };
3370
3371
3372
3373
3374
3375 if (matchOuterCond(m_Specific(InnerSel.Cond))) {
3376
3379
3380 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3381 InnerSel.Cond = NotInnerCond;
3382 } else
3383 return nullptr;
3384
3386 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
3387 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
3388 SelInner->takeName(InnerSelVal);
3390 IsAndVariant ? SelInner : InnerSel.TrueVal,
3391 !IsAndVariant ? SelInner : InnerSel.FalseVal);
3392}
3393
3394
3395
3396
3397static bool impliesPoisonOrCond(const Value *ValAssumedPoison, const Value *V,
3400 return true;
3401
3402
3403
3405 Value *LHS = ICmp->getOperand(0);
3406 const APInt *RHSC1;
3407 const APInt *RHSC2;
3409 if (ICmp->hasSameSign() &&
3420 *RHSC2);
3421 }
3422 }
3423
3424 return false;
3425}
3426
3428 Value *CondVal = SI.getCondition();
3431 Type *SelType = SI.getType();
3432
3433
3434
3435
3438 return nullptr;
3439
3443
3444
3445
3446
3448 if (impliesPoisonOrCond(FalseVal, CondVal, false)) {
3449
3450 return BinaryOperator::CreateOr(CondVal, FalseVal);
3451 }
3452
3454 impliesPoisonOrCond(FalseVal, B, false)) {
3455
3457 SI, Builder.CreateLogicalOr(A, Builder.CreateOr(B, FalseVal), "",
3459 ? nullptr
3461 }
3462
3463
3469 auto AndFactorization = [&](Value *Common, Value *InnerCond,
3470 Value *InnerVal,
3471 bool SelFirst = false) -> Instruction * {
3472 Value *InnerSel = Builder.CreateSelect(InnerCond, One, InnerVal);
3473 if (SelFirst)
3475 if (FalseLogicAnd || (CondLogicAnd && Common == A))
3477 else
3478 return BinaryOperator::CreateAnd(Common, InnerSel);
3479 };
3480
3482 return AndFactorization(A, B, D);
3484 return AndFactorization(A, B, C);
3486 return AndFactorization(B, A, D);
3488 return AndFactorization(B, A, C, CondLogicAnd && FalseLogicAnd);
3489 }
3490 }
3491
3493 if (impliesPoisonOrCond(TrueVal, CondVal, true)) {
3494
3495 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3496 }
3497
3499 impliesPoisonOrCond(TrueVal, B, true)) {
3500
3502 SI, Builder.CreateLogicalAnd(A, Builder.CreateAnd(B, TrueVal), "",
3504 ? nullptr
3506 }
3507
3508
3514 auto OrFactorization = [&](Value *Common, Value *InnerCond,
3515 Value *InnerVal,
3516 bool SelFirst = false) -> Instruction * {
3517 Value *InnerSel = Builder.CreateSelect(InnerCond, InnerVal, Zero);
3518 if (SelFirst)
3520 if (TrueLogicOr || (CondLogicOr && Common == A))
3522 else
3523 return BinaryOperator::CreateOr(Common, InnerSel);
3524 };
3525
3527 return OrFactorization(A, B, D);
3529 return OrFactorization(A, B, C);
3531 return OrFactorization(B, A, D);
3533 return OrFactorization(B, A, C, CondLogicOr && TrueLogicOr);
3534 }
3535 }
3536
3537
3538
3539
3541 Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());
3543 SelectInst *NewSI =
3546 return NewSI;
3547 }
3548
3550 Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());
3552 SelectInst *NewSI =
3555 return NewSI;
3556 }
3557
3558
3559
3564 SelectInst *NewSI =
3568 }
3569
3570
3571
3576 SelectInst *NewSI =
3580 }
3581
3582
3586
3590
3591
3594 return BinaryOperator::CreateXor(A, B);
3595
3596
3597 if (match(CondVal,
3599 Value *OrV = Builder.CreateSelect(C, One, FalseVal);
3601 }
3602
3605 Value *OrV = Builder.CreateSelect(NotC, One, TrueVal);
3607 }
3608 }
3609
3612 Value *AndV = Builder.CreateSelect(NotC, FalseVal, Zero);
3614 }
3615 }
3616
3617 if (match(CondVal,
3619 Value *AndV = Builder.CreateSelect(C, TrueVal, Zero);
3621 }
3622
3628 auto *FI = new FreezeInst(*Y, (*Y)->getName() + ".fr");
3632 }
3633
3634 if (auto *V = foldBooleanAndOr(CondVal, Op1, SI, IsAnd,
3635 true))
3637 }
3638
3639
3640
3641
3645 if (Res && *Res == false)
3647 }
3651 if (Res && *Res == false)
3653 }
3654
3655
3656
3660 if (Res && *Res == true)
3662 }
3666 if (Res && *Res == true)
3668 }
3669
3672
3673
3674
3675
3676
3681 bool MayNeedFreeze = SelCond && SelFVal &&
3682 match(SelFVal->getTrueValue(),
3684 if (MayNeedFreeze)
3687 Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;
3689 SelCond) {
3691 } else if (match(FalseVal,
3693 SelFVal) {
3696 return NewSI;
3697 } else {
3698 return createSelectInstWithUnknownProfile(C, A, B);
3699 }
3700 }
3702 }
3703
3704
3705
3706
3707
3712 bool MayNeedFreeze = SelCond && SelFVal &&
3713 match(SelCond->getTrueValue(),
3715 if (MayNeedFreeze)
3718 Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;
3720 SelCond) {
3723 return NewSI;
3725 SelFVal) {
3727 } else {
3728 return createSelectInstWithUnknownProfile(C, B, A);
3729 }
3730 }
3732 }
3733 }
3734
3735 return nullptr;
3736}
3737
3738
3739
3743 bool &ShouldDropNoWrap) {
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3765
3766 ShouldDropNoWrap = false;
3767
3768
3769
3770
3771
3772 auto MatchForward = [&](Value *CommonAncestor) {
3773 const APInt *C = nullptr;
3774 if (CtlzOp == CommonAncestor)
3775 return true;
3777 ShouldDropNoWrap = true;
3779 return true;
3780 }
3782 ShouldDropNoWrap = true;
3784 return true;
3785 }
3788 return true;
3789 }
3790 return false;
3791 };
3792
3793 const APInt *C = nullptr;
3794 Value *CommonAncestor;
3795 if (MatchForward(Cond0)) {
3796
3799 if (!MatchForward(CommonAncestor))
3800 return false;
3801
3802 } else {
3803 return false;
3804 }
3805
3806
3807
3808
3809
3813}
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3837 Type *SelType = SI.getType();
3839
3843 const APInt *Cond1;
3844 Value *Cond0, *Ctlz, *CtlzOp;
3846 return nullptr;
3847
3851 }
3852
3853 bool ShouldDropNoWrap;
3854
3860 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp, BitWidth,
3861 ShouldDropNoWrap))
3862 return nullptr;
3863
3864 if (ShouldDropNoWrap) {
3867 }
3868
3869
3870
3871
3872
3873
3874
3876
3881 Builder.CreateAnd(Neg, ConstantInt::get(SelType, BitWidth - 1));
3884}
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3898 Value *TV = SI.getTrueValue();
3899 Value *FV = SI.getFalseValue();
3900
3901 CmpPredicate Pred;
3904 return nullptr;
3905
3907 return nullptr;
3908
3909
3910
3913 return nullptr;
3916 }
3917
3920 auto FlippedPredAndConst =
3922 if (!FlippedPredAndConst)
3923 return nullptr;
3924 Pred = FlippedPredAndConst->first;
3925 RHS = FlippedPredAndConst->second;
3926 } else {
3927 return nullptr;
3928 }
3929 }
3930
3931
3932
3933
3934
3939 }
3941
3942 bool Replace = false;
3943 CmpPredicate ExtendedCmpPredicate;
3944
3945
3951 Replace = true;
3952
3953
3954
3960 Replace = true;
3961
3962
3963 CmpPredicate FalseBranchSelectPredicate;
3964 const APInt *InnerTV, *InnerFV;
3970 FalseBranchSelectPredicate =
3973 }
3974
3975 if (!InnerTV->isOne()) {
3978 }
3979
3983 Replace = true;
3984 }
3985 }
3986
3987
3989 const APInt *C;
3991 CmpPredicate InnerPred;
3992 Value *InnerRHS;
3993 const APInt *InnerTV, *InnerFV;
3997
3998
4002 bool CanSubOne = IsSigned ? ->isMinSignedValue() :
->isMinValue();
4003 if (CanSubOne) {
4004 APInt Cminus1 = *C - 1;
4006 Replace = true;
4007 }
4008 }
4009
4010
4012 InnerFV->isOne()) {
4014 bool CanAddOne = IsSigned ? ->isMaxSignedValue() :
->isMaxValue();
4015 if (CanAddOne) {
4016 APInt Cplus1 = *C + 1;
4018 Replace = true;
4019 }
4020 }
4021 }
4022 }
4023 }
4024
4025 Intrinsic::ID IID = IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;
4026 if (Replace)
4028 SI, Builder.CreateIntrinsic(SI.getType(), IID, {LHS, RHS}));
4029 return nullptr;
4030}
4031
4035
4038}
4039
4043 bool SelectIsNSZ) {
4048
4049
4052 }
4053
4054 return false;
4055}
4056
4057
4058
4060 unsigned Depth) {
4062 return false;
4063
4064
4065
4067 return true;
4068
4072 return false;
4074 }
4076 return Op->getType()->isIntOrIntVectorTy() &&
4077 hasAffectedValue(Op, Affected, Depth + 1);
4078 });
4079 }
4080
4081 return false;
4082}
4083
4084
4085
4088
4089
4091 if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())
4092 return nullptr;
4093
4094 auto TryFoldIntoAddConstant =
4097
4098
4100 return nullptr;
4101
4103 return nullptr;
4104
4106 Swapped ? X : Z, "", &SI);
4108
4111
4112
4119
4120 return NewFAdd;
4121 };
4122
4123
4124
4125
4126
4131
4132
4133
4134
4137 return TryFoldIntoAddConstant(Pred, X, Z, FAdd, C, false);
4138
4141 return TryFoldIntoAddConstant(Pred, X, Z, FAdd, C, true);
4142
4143 return nullptr;
4144}
4145
4147 Value *FalseVal,
4150
4153 return nullptr;
4154
4157 bool CreateAnd = false;
4159 Value *CmpLHS, *CmpRHS;
4160
4164 return nullptr;
4165
4166 V = CmpLHS;
4167 const APInt *AndRHS;
4169 return nullptr;
4170
4171 AndMask = *AndRHS;
4174 AndMask = Res->Mask;
4175 V = Res->X;
4179 return nullptr;
4180
4181 Pred = Res->Pred;
4182 CreateAnd = true;
4183 } else {
4184 return nullptr;
4185 }
4187 V = Trunc->getOperand(0);
4188 AndMask = APInt(V->getType()->getScalarSizeInBits(), 1);
4190 CreateAnd = !Trunc->hasNoUnsignedWrap();
4191 } else {
4192 return nullptr;
4193 }
4194
4197
4199 CreateAnd, Builder))
4200 return X;
4201
4203 CreateAnd, Builder))
4204 return X;
4205
4206 return nullptr;
4207}
4208
4210 Value *CondVal = SI.getCondition();
4213 Type *SelType = SI.getType();
4214
4216 SQ.getWithInstruction(&SI)))
4218
4219 if (Instruction *I = canonicalizeSelectToShuffle(SI))
4220 return I;
4221
4222 if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, *this))
4223 return I;
4224
4225
4226
4227
4233 true))
4235
4238 true))
4240
4245 return &SI;
4246 }
4247
4249 return R;
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4262
4264 return new ZExtInst(CondVal, SelType);
4265
4266
4268 return new SExtInst(CondVal, SelType);
4269
4270
4272 Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());
4273 return new ZExtInst(NotCond, SelType);
4274 }
4275
4276
4278 Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());
4279 return new SExtInst(NotCond, SelType);
4280 }
4281 }
4282
4284
4287 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
4288
4289 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
4290 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
4291
4292
4293
4294
4295
4298 Value *NewCond = Builder.CreateFCmpFMF(InvPred, Cmp0, Cmp1, FCmp,
4299 FCmp->getName() + ".inv");
4300
4301 FastMathFlags FMF = SI.getFastMathFlags();
4302 if (FCmp->hasNoNaNs())
4304 if (FCmp->hasNoInfs())
4307 Builder.CreateSelectFMF(NewCond, FalseVal, TrueVal, FMF);
4309 }
4310 }
4311
4312 if (SIFPOp) {
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326 Value *MatchCmp0 = nullptr;
4327 Value *MatchCmp1 = nullptr;
4328
4329
4330
4337 }
4338
4339 if (Cmp0 == MatchCmp0 &&
4340 matchFMulByZeroIfResultEqZero(*this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
4341 SI, SIFPOp->hasNoSignedZeros()))
4343 }
4344 }
4345
4346 if (SIFPOp) {
4347
4348
4350
4351
4352
4353 if (SIFPOp->hasNoNaNs() &&
4354 (SIFPOp->hasNoSignedZeros() ||
4355 (SIFPOp->hasOneUse() &&
4359 Value *BinIntr =
4360 Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, X, Y, &SI);
4362 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
4363 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
4364 }
4366 }
4367
4369 Value *BinIntr =
4370 Builder.CreateBinaryIntrinsic(Intrinsic::minnum, X, Y, &SI);
4372 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
4373 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
4374 }
4376 }
4377 }
4378 }
4379
4380
4381 if (Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *this))
4382 return Fabs;
4383
4384
4387 return NewSel;
4388
4392
4393 if (Value *V = foldSelectBitTest(SI, CondVal, TrueVal, FalseVal, Builder, SQ))
4395
4396 if (Instruction *Add = foldAddSubSelect(SI, Builder))
4397 return Add;
4398 if (Instruction *Add = foldOverflowingAddSubSelect(SI, Builder))
4399 return Add;
4401 return Or;
4403 return Mul;
4404
4405
4408 if (TI && FI && TI->getOpcode() == FI->getOpcode())
4410 return IV;
4411
4413 return I;
4414
4415 if (Instruction *I = foldSelectWithSRem(SI, *this, Builder))
4416 return I;
4417
4418
4419
4420 auto SelectGepWithBase = [&](GetElementPtrInst *Gep, Value *Base,
4421 bool Swap) -> GetElementPtrInst * {
4425 return nullptr;
4428 return nullptr;
4430 Value *NewT = Idx;
4432 if (Swap)
4435 Builder.CreateSelect(CondVal, NewT, NewF, SI.getName() + ".idx", &SI);
4438 };
4440 if (auto *NewGep = SelectGepWithBase(TrueGep, FalseVal, false))
4441 return NewGep;
4443 if (auto *NewGep = SelectGepWithBase(FalseGep, TrueVal, true))
4444 return NewGep;
4445
4446
4448 if (Instruction *FoldI = foldSelectIntoOp(SI, TrueVal, FalseVal))
4449 return FoldI;
4450
4454 auto SPF = SPR.Flavor;
4455 if (SPF) {
4456 Value *LHS2, *RHS2;
4459 RHS2, SI, SPF, RHS))
4460 return R;
4463 RHS2, SI, SPF, LHS))
4464 return R;
4465 }
4466
4468
4469
4470
4471
4472 bool IsCastNeeded = LHS->getType() != SelType;
4475 if (IsCastNeeded ||
4477 ((CmpLHS != LHS && CmpLHS != RHS) ||
4478 (CmpRHS != LHS && CmpRHS != RHS)))) {
4480
4484 else
4487
4489 if (!IsCastNeeded)
4491
4492 Value *NewCast = Builder.CreateCast(CastOp, NewSI, SelType);
4494 }
4495 }
4496 }
4497
4498
4501 return NV;
4502
4504 if (TrueSI->getCondition()->getType() == CondVal->getType()) {
4505
4506
4507 if (Value *V = simplifyNestedSelectsUsingImpliedCond(
4508 *TrueSI, CondVal, true, DL))
4510
4511
4512
4513
4514
4515 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
4516 Value *And = Builder.CreateLogicalAnd(CondVal, TrueSI->getCondition());
4519 return &SI;
4520 }
4521 }
4522 }
4524 if (FalseSI->getCondition()->getType() == CondVal->getType()) {
4525
4526
4527 if (Value *V = simplifyNestedSelectsUsingImpliedCond(
4528 *FalseSI, CondVal, false, DL))
4530
4531
4532 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
4533 Value *Or = Builder.CreateLogicalOr(CondVal, FalseSI->getCondition());
4536 return &SI;
4537 }
4538 }
4539 }
4540
4541
4542
4543
4544
4545
4546
4547 BinaryOperator *TrueBO;
4550 if (TrueBOSI->getCondition() == CondVal) {
4551 replaceOperand(*TrueBO, 0, TrueBOSI->getTrueValue());
4553 return &SI;
4554 }
4555 }
4557 if (TrueBOSI->getCondition() == CondVal) {
4558 replaceOperand(*TrueBO, 1, TrueBOSI->getTrueValue());
4560 return &SI;
4561 }
4562 }
4563 }
4564
4565
4566 BinaryOperator *FalseBO;
4569 if (FalseBOSI->getCondition() == CondVal) {
4570 replaceOperand(*FalseBO, 0, FalseBOSI->getFalseValue());
4572 return &SI;
4573 }
4574 }
4576 if (FalseBOSI->getCondition() == CondVal) {
4577 replaceOperand(*FalseBO, 1, FalseBOSI->getFalseValue());
4579 return &SI;
4580 }
4581 }
4582 }
4583
4588 SI.swapValues();
4589 SI.swapProfMetadata();
4590 return &SI;
4591 }
4592
4594 return I;
4595
4596
4597
4598
4599
4600
4602 KnownBits Known(1);
4608 }
4609
4610 if (Instruction *BitCastSel = foldSelectCmpBitcasts(SI, Builder))
4611 return BitCastSel;
4612
4613
4614 if (Value *V = foldSelectCmpXchg(SI))
4616
4619
4620 if (Instruction *Funnel = foldSelectFunnelShift(SI, Builder))
4621 return Funnel;
4622
4623 if (Instruction *Copysign = foldSelectToCopysign(SI, Builder))
4624 return Copysign;
4625
4626 if (Instruction *PN = foldSelectToPhi(SI, DT, Builder))
4628
4629 if (Value *V = foldRoundUpIntegerWithPow2Alignment(SI, Builder))
4631
4632 if (Value *V = foldSelectIntoAddConstant(SI, Builder))
4634
4635
4636
4644 MaskedInst->setArgOperand(2, FalseVal );
4646 }
4647
4654 (CondVal->getType() == Mask->getType())) {
4655
4656
4657
4658
4659 bool CanMergeSelectIntoLoad = false;
4661 CanMergeSelectIntoLoad = match(V, m_Zero());
4662
4663 if (CanMergeSelectIntoLoad) {
4666 MaskedInst->setArgOperand(2, TrueVal );
4668 }
4669 }
4670
4671 if (Instruction *I = foldSelectOfSymmetricSelect(SI, Builder))
4672 return I;
4673
4674 if (Instruction *I = foldNestedSelects(SI, Builder))
4675 return I;
4676
4677
4678
4679
4680
4682 return &SI;
4683
4684 if (Instruction *I = foldBitCeil(SI, Builder, *this))
4685 return I;
4686
4688 return I;
4689
4691 return I;
4692
4693
4694
4695
4696
4697
4698 auto FoldSelectWithAndOrCond = [&](bool IsAnd, Value *A,
4699 Value *B) -> Instruction * {
4701 SQ.getWithInstruction(&SI))) {
4704
4705
4706
4707
4709 if (NewTrueVal == TrueVal && NewFalseVal == FalseVal &&
4711 MDFrom = &SI;
4712 }
4714 MDFrom);
4715 }
4716
4717
4720 if (Value *V = canonicalizeSPF(*Cmp, TrueVal, FalseVal, *this))
4722 IsAnd ? FalseVal : V);
4723 }
4724
4725 return nullptr;
4726 };
4727
4730 if (Instruction *I = FoldSelectWithAndOrCond( true, LHS, RHS))
4731 return I;
4732 if (Instruction *I = FoldSelectWithAndOrCond( true, RHS, LHS))
4733 return I;
4735 if (Instruction *I = FoldSelectWithAndOrCond( false, LHS, RHS))
4736 return I;
4737 if (Instruction *I = FoldSelectWithAndOrCond( false, RHS, LHS))
4738 return I;
4739 } else {
4740
4741
4743 if (Instruction *I = FoldSelectWithAndOrCond( true, LHS, RHS))
4744 return I;
4746 if (Instruction *I = FoldSelectWithAndOrCond( false, LHS, RHS))
4747 return I;
4748 }
4749 }
4750
4751
4753 return BinaryOperator::CreateXor(CondVal, FalseVal);
4754
4755
4756
4759
4760 CondContext CC(CondVal);
4762 CC.AffectedValues.insert(V);
4763 });
4764 SimplifyQuery Q = SQ.getWithInstruction(&SI).getWithCondContext(CC);
4765 if (!CC.AffectedValues.empty()) {
4767 hasAffectedValue(TrueVal, CC.AffectedValues, 0)) {
4771 ConstantInt::get(SelType, Known.getConstant()));
4772 }
4773
4774 CC.Invert = true;
4776 hasAffectedValue(FalseVal, CC.AffectedValues, 0)) {
4780 ConstantInt::get(SelType, Known.getConstant()));
4781 }
4782 }
4783 }
4784
4785
4786
4787
4788
4791 if (TrueVal == Trunc)
4793 if (FalseVal == Trunc)
4795 }
4797 if (TrueVal == Trunc)
4800 if (FalseVal == Trunc)
4802 }
4803
4804 Value *MaskedLoadPtr;
4808 SI, Builder.CreateMaskedLoad(
4809 TrueVal->getType(), MaskedLoadPtr,
4811 CondVal, FalseVal));
4812
4813
4814
4815
4816 unsigned BitWidth = SI.getType()->getScalarSizeInBits();
4817 CmpPredicate Pred;
4818 Value *CmpLHS, *CmpRHS;
4819
4820
4821
4822
4833
4835 SI.getModule(), Intrinsic::scmp, {SI.getType(), SI.getType()});
4836 return CallInst::Create(Scmp, {CmpLHS, ConstantInt::get(SI.getType(), 0)});
4837 }
4838
4839 return nullptr;
4840}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file provides internal interfaces used to implement the InstCombine.
static Value * foldSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
Try to fold a select to a min/max intrinsic.
Definition InstCombineSelect.cpp:586
static Value * canonicalizeSaturatedAddSigned(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
Definition InstCombineSelect.cpp:1132
static Value * canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
Definition InstCombineSelect.cpp:1207
static Instruction * foldSetClearBits(SelectInst &Sel, InstCombiner::BuilderTy &Builder)
Canonicalize a set or clear of a masked set of constant bits to select-of-constants form.
Definition InstCombineSelect.cpp:856
static Instruction * foldSelectICmpAndAnd(Type *SelType, const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, Y), 0), (and (lshr X, Z), 1), 1) into: zext (icmp ne i32 (a...
Definition InstCombineSelect.cpp:647
static unsigned getSelectFoldableOperands(BinaryOperator *I)
We want to turn code that looks like this: C = or A, B D = select cond, C, A into: C = select cond,...
Definition InstCombineSelect.cpp:226
static Value * canonicalizeSaturatedSubtract(const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)
Transform patterns such as (a > b) ?
Definition InstCombineSelect.cpp:963
static Value * foldAbsDiff(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
Try to match patterns with select and subtract as absolute difference.
Definition InstCombineSelect.cpp:1222
static Instruction * foldSelectZeroOrFixedOp(SelectInst &SI, InstCombinerImpl &IC)
Definition InstCombineSelect.cpp:899
static Instruction * foldSelectBinOpIdentity(SelectInst &Sel, const TargetLibraryInfo &TLI, InstCombinerImpl &IC)
Replace a select operand based on an equality comparison with the identity constant of a binop.
Definition InstCombineSelect.cpp:61
static Value * foldSelectICmpAnd(SelectInst &Sel, Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, InstCombiner::BuilderTy &Builder)
This folds: select (icmp eq (and X, C1)), TC, FC iff C1 is a power 2 and the difference between TC an...
Definition InstCombineSelect.cpp:128
static Value * foldSelectICmpAndZeroShl(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, C1), 0), 0, (shl [nsw/nuw] X, C2)); iff C1 is a mask and th...
Definition InstCombineSelect.cpp:695
static Value * canonicalizeSaturatedAddUnsigned(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
Definition InstCombineSelect.cpp:1031
static Value * foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp sgt x, C), lshr (X, Y), ashr (X, Y)); iff C s>= -1 (select (icmp slt x...
Definition InstCombineSelect.cpp:733
static bool isSelect01(const APInt &C1I, const APInt &C2I)
Definition InstCombineSelect.cpp:492
static Value * foldSelectICmpAndBinOp(Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, C1), 0), Y, (BinOp Y, C2)) into: IF C2 u>= C1 (BinOp Y,...
Definition InstCombineSelect.cpp:788
This file provides the interface for the instcombine pass implementation.
Machine Check Debug Module
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static const uint32_t IV[8]
bool bitwiseIsEqual(const APFloat &RHS) const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
uint64_t getZExtValue() const
Get zero extended value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
bool isMinValue() const
Determine if this is the smallest unsigned value.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned countLeadingZeros() const
unsigned logBase2() const
bool isMask(unsigned numBits) const
bool isMaxSignedValue() const
Determine if this is the largest signed value.
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool isOne() const
Determine if this is a value of 1.
bool isMaxValue() const
Determine if this is the largest unsigned value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
An instruction that atomically checks whether a specified value is in a memory location,...
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static bool isFPPredicate(Predicate P)
bool isNonStrictPredicate() const
static bool isRelational(Predicate P)
Return true if the predicate is relational (not EQ or NE).
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
static LLVM_ABI bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
Predicate getFlippedStrictnessPredicate() const
For predicate of kind "is X or equal to 0" returns the predicate "is X".
bool isIntPredicate() const
static LLVM_ABI bool isOrdered(Predicate predicate)
Determine if the predicate is an ordered operation.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI std::optional< CmpPredicate > getMatching(CmpPredicate A, CmpPredicate B)
Compares two CmpPredicates taking samesign into account and returns the canonicalized CmpPredicate if...
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
This class represents a range of values.
LLVM_ABI ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
LLVM_ABI bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other?
static LLVM_ABI ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
static LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
LLVM_ABI ConstantRange binaryNot() const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
LLVM_ABI ConstantRange binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const
Return a new range representing the possible values resulting from an application of the specified bi...
LLVM_ABI ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
This is an important base class in LLVM.
static LLVM_ABI Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isOneValue() const
Returns true if the value is one.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Tagged union holding either a T or a Error.
Utility class for floating point operations which can have information about relaxed accuracy require...
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags.
Convenience struct for specifying and reasoning about fast-math flags.
static FastMathFlags intersectRewrite(FastMathFlags LHS, FastMathFlags RHS)
Intersect rewrite-based flags.
bool noSignedZeros() const
static FastMathFlags unionValue(FastMathFlags LHS, FastMathFlags RHS)
Union value flags.
void setNoSignedZeros(bool B=true)
void setNoNaNs(bool B=true)
void setNoInfs(bool B=true)
This class represents a freeze function that returns random concrete value if an operand is either a ...
Value * getPointerOperand()
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Type * getSourceElementType() const
LLVM_ABI GEPNoWrapFlags getNoWrapFlags() const
Get the nowrap flags for the GEP instruction.
This instruction compares its operands according to the predicate given to the constructor.
static CmpPredicate getSwappedCmpPredicate(CmpPredicate Pred)
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
CmpPredicate getInverseCmpPredicate() const
static bool isGT(Predicate P)
Return true if the predicate is SGT or UGT.
static CmpPredicate getInverseCmpPredicate(CmpPredicate Pred)
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Common base class shared among various IRBuilders.
Value * CreateFAdd(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
LLVM_ABI CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getFalse()
Get the constant value for i1 false.
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Instruction * foldSelectToCmp(SelectInst &SI)
bool fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF, const Instruction *CtxI) const
Check if fmul MulVal, +0.0 will yield +0.0 (or signed zero is ignorable).
KnownFPClass computeKnownFPClass(Value *Val, FastMathFlags FMF, FPClassTest Interested=fcAllFlags, const Instruction *CtxI=nullptr, unsigned Depth=0) const
Instruction * foldSelectEqualityTest(SelectInst &SI)
Instruction * foldSelectValueEquivalence(SelectInst &SI, CmpInst &CI)
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Instruction * foldVectorSelect(SelectInst &Sel)
Value * SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &PoisonElts, unsigned Depth=0, bool AllowMultipleUsers=false) override
The specified value produces a vector with any number of elements.
Instruction * foldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, Instruction &Outer, SelectPatternFlavor SPF2, Value *C)
Instruction * foldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI)
We have (select c, TI, FI), and we know that TI and FI have the same opcode.
Definition InstCombineSelect.cpp:249
bool replaceInInstruction(Value *V, Value *Old, Value *New, unsigned Depth=0)
Instruction * foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Instruction * foldSelectIntoOp(SelectInst &SI, Value *, Value *)
Try to fold the select into one of the operands to allow further optimization.
Definition InstCombineSelect.cpp:500
Value * foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal, Value *FalseVal)
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
The core instruction combiner logic.
const DataLayout & getDataLayout() const
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
Instruction * InsertNewInstBefore(Instruction *New, BasicBlock::iterator Old)
Inserts an instruction New before instruction Old.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI)
void replaceUse(Use &U, Value *NewValue)
Replace use and add the previously used value to the worklist.
static bool isCanonicalPredicate(CmpPredicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
static Constant * AddOne(Constant *C)
Add one to a Constant.
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)
LLVM_ABI bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
LLVM_ABI bool isSameOperationAs(const Instruction *I, unsigned flags=0) const LLVM_READONLY
This function determines if the specified instruction executes the same operation as the current one.
LLVM_ABI void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
LLVM_ABI bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
LLVM_ABI void setHasNoNaNs(bool B)
Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
LLVM_ABI void swapProfMetadata()
If the instruction has "branch_weights" MD_prof metadata and the MDNode has three operands (including...
LLVM_ABI void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
const Value * getFalseValue() const
void swapValues()
Swap the true and false values of the select instruction.
const Value * getCondition() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
const Value * getTrueValue() const
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool contains(ConstPtrType Ptr) const
A SetVector that performs no allocations if smaller than a certain size.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
static UnaryOperator * CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI const Value * DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const
Translate PHI node to its predecessor from the given basic block.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Represents an op.with.overflow intrinsic.
This class represents zero extension of integer types.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
int getMinValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return the minimum value of an extendable operand.
int getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return the maximum value of an extendable operand.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
BinaryOpc_match< LHS, RHS, false > m_BinOp(unsigned Opcode, const LHS &L, const RHS &R)
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< cst_pred_ty< is_all_ones, false >, ValTy, Instruction::Xor, true > m_NotForbidPoison(const ValTy &V)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FMul, true > m_c_FMul(const LHS &L, const RHS &R)
Matches FMul with LHS and RHS in either order.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
CommutativeBinaryIntrinsic_match< IntrID, T0, T1 > m_c_Intrinsic(const T0 &Op0, const T1 &Op1)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
LogicalOp_match< LHS, RHS, Instruction::And > m_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R either in the form of L & R or L ?
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)
Matches integer division operations.
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)
Matches a 'Neg' as 'sub nsw 0, V'.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedLoad(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedLoad Intrinsic.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_IntrinsicIntrinsic::fabs(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmin_pred_ty > > m_OrdOrUnordFMin(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point minimum function.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
cst_pred_ty< is_any_apint > m_AnyIntegralConstant()
Match an integer or vector with any integral constant.
bind_ty< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
ap_match< APInt > m_APIntForbidPoison(const APInt *&Res)
Match APInt while forbidding poison in splat vector constants.
cst_pred_ty< is_strictlypositive > m_StrictlyPositive()
Match an integer or vector of strictly positive values.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
auto m_c_LogicalOp(const LHS &L, const RHS &R)
Matches either L && R or L || R with LHS and RHS in either order.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedGather(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedGather Intrinsic.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmax_pred_ty > > m_OrdOrUnordFMax(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point maximum function.
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
cst_pred_ty< is_maxsignedvalue > m_MaxSignedValue()
Match an integer or vector with values having all bits except for the high bit set (0x7f....
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > > > m_MaxOrMin(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
class_match< BasicBlock > m_BasicBlock()
Match an arbitrary basic block value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
LogicalOp_match< LHS, RHS, Instruction::Or, true > m_c_LogicalOr(const LHS &L, const RHS &R)
Matches L || R with LHS and RHS in either order.
SpecificCmpClass_match< LHS, RHS, ICmpInst, true > m_c_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
MatchFunctor< Val, Pattern > match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
ElementType
The element type of an SRV or UAV resource.
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI Constant * ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS, Constant *RHS, Type *Ty, Instruction *FMFSource)
LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
LLVM_ABI CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)
Return the canonical comparison predicate for the specified minimum/maximum flavor.
LLVM_ABI bool canIgnoreSignBitOfZero(const Use &U)
Return true if the sign bit of the FP value can be ignored by the user when the value is zero.
LLVM_ABI bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
constexpr unsigned MaxAnalysisRecursionDepth
SelectPatternFlavor
Specific patterns of select instructions we can match.
@ SPF_ABS
Floating point maxnum.
@ SPF_NABS
Absolute value.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)
Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...
LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
LLVM_ABI SelectPatternResult getSelectPattern(CmpInst::Predicate Pred, SelectPatternNaNBehavior NaNBehavior=SPNB_NA, bool Ordered=false)
Determine the pattern for predicate X Pred Y ? X : Y.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
LLVM_ABI bool cannotBeNegativeZero(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if we can prove that the specified FP value is never equal to -0.0.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
FunctionAddr VTableAddr Count
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
LLVM_ABI Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool isNotCrossLaneOperation(const Instruction *I)
Return true if the instruction doesn't potentially cross vector lanes.
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
constexpr int PoisonMaskElem
LLVM_ABI Intrinsic::ID getMinMaxIntrinsic(SelectPatternFlavor SPF)
Convert given SPF to equivalent min/max intrinsic.
LLVM_ABI SelectPatternResult matchDecomposedSelectPattern(CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, FastMathFlags FMF=FastMathFlags(), Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Determine the pattern that a select with the given compare as its predicate and given values as its t...
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)
Don't use information from its non-constant operands.
constexpr unsigned BitWidth
LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...
LLVM_ABI Value * simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags=nullptr)
See if V simplifies when its operand Op is replaced with RepOp.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
auto predecessors(const MachineBasicBlock *BB)
LLVM_ABI std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)
Convert an integer comparison with a constant RHS into an equivalent form with the strictness flipped...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
cl::opt< bool > ProfcheckDisableMetadataFixes("profcheck-disable-metadata-fixes", cl::Hidden, cl::init(false), cl::desc("Disable metadata propagation fixes discovered through Issue #147390"))
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
bool isCheckForZeroAndMulWithOverflow(Value *Op0, Value *Op1, bool IsAnd, Use *&Y)
Match one of the patterns up to the select/logic op: Op0 = icmp ne i4 X, 0 Agg = call { i4,...
LLVM_ABI Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
LLVM_ABI std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)
Return true if RHS is known to be implied true by LHS.
std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
LLVM_ABI bool canIgnoreSignBitOfNaN(const Use &U)
Return true if the sign bit of the FP value can be ignored by the user when the value is NaN.
LLVM_ABI void findValuesAffectedByCondition(Value *Cond, bool IsAssume, function_ref< void(Value *)> InsertAffected)
Call InsertAffected on all Values whose known bits / value may be affected by the condition Cond.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
bool isConstant() const
Returns true if we know the value of all bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
bool signBitIsZeroOrNaN() const
Return true if the sign bit must be 0, ignoring the sign of nans.
SelectPatternFlavor Flavor
bool Ordered
Only applicable if Flavor is SPF_FMINNUM or SPF_FMAXNUM.
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
SimplifyQuery getWithInstruction(const Instruction *I) const