LLVM: lib/Analysis/InstructionSimplify.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
20
45#include
46#include
47using namespace llvm;
49
50#define DEBUG_TYPE "instsimplify"
51
53
54STATISTIC(NumExpand, "Number of expansions");
55STATISTIC(NumReassoc, "Number of reassociations");
56
58 unsigned);
63 unsigned);
72 unsigned);
74 unsigned);
82 unsigned MaxRecurse);
83
84
85
87
88
89
91
92
94 CmpInst *Cmp = dyn_cast(V);
95 if (!Cmp)
96 return false;
98 Value *CLHS = Cmp->getOperand(0), *CRHS = Cmp->getOperand(1);
99 if (CPred == Pred && CLHS == LHS && CRHS == RHS)
100 return true;
102 CRHS == LHS;
103}
104
105
106
107
108
109
112 unsigned MaxRecurse, Constant *TrueOrFalse) {
114 if (SimplifiedCmp == Cond) {
115
116 return TrueOrFalse;
118
119
120 return TrueOrFalse;
121 }
122 return SimplifiedCmp;
123}
124
125
128 unsigned MaxRecurse) {
131}
132
133
136 unsigned MaxRecurse) {
139}
140
141
142
146 unsigned MaxRecurse) {
147
148
149
150
151
152
155 return V;
156
157
160 return V;
161
162
166 return V;
167 return nullptr;
168}
169
170
173 if ()
174
175 return true;
176
177
178 if (DT)
180
181
182
183 if (I->getParent()->isEntryBlock() && !isa(I) &&
184 !isa(I))
185 return true;
186
187 return false;
188}
189
190
191
192
196 auto *B = dyn_cast(V);
197 if ( || B->getOpcode() != OpcodeToExpand)
198 return nullptr;
199 Value *B0 = B->getOperand(0), *B1 = B->getOperand(1);
202 if (!L)
203 return nullptr;
206 if (!R)
207 return nullptr;
208
209
210 if ((L == B0 && R == B1) ||
212 ++NumExpand;
213 return B;
214 }
215
216
218 if (!S)
219 return nullptr;
220
221 ++NumExpand;
222 return S;
223}
224
225
226
231 unsigned MaxRecurse) {
232
233 if (!MaxRecurse--)
234 return nullptr;
235
236 if (Value *V = expandBinOp(Opcode, L, R, OpcodeToExpand, Q, MaxRecurse))
237 return V;
238 if (Value *V = expandBinOp(Opcode, R, L, OpcodeToExpand, Q, MaxRecurse))
239 return V;
240 return nullptr;
241}
242
243
244
248 unsigned MaxRecurse) {
250
251
252 if (!MaxRecurse--)
253 return nullptr;
254
257
258
259 if (Op0 && Op0->getOpcode() == Opcode) {
263
264
266
267
268 if (V == B)
269 return LHS;
270
272 ++NumReassoc;
273 return W;
274 }
275 }
276 }
277
278
279 if (Op1 && Op1->getOpcode() == Opcode) {
283
284
286
287
288 if (V == B)
289 return RHS;
290
292 ++NumReassoc;
293 return W;
294 }
295 }
296 }
297
298
300 return nullptr;
301
302
303 if (Op0 && Op0->getOpcode() == Opcode) {
307
308
310
311
312 if (V == A)
313 return LHS;
314
316 ++NumReassoc;
317 return W;
318 }
319 }
320 }
321
322
323 if (Op1 && Op1->getOpcode() == Opcode) {
327
328
330
331
332 if (V == C)
333 return RHS;
334
336 ++NumReassoc;
337 return W;
338 }
339 }
340 }
341
342 return nullptr;
343}
344
345
346
347
348
351 unsigned MaxRecurse) {
352
353 if (!MaxRecurse--)
354 return nullptr;
355
357 if (isa(LHS)) {
358 SI = cast(LHS);
359 } else {
360 assert(isa(RHS) && "No select instruction operand!");
361 SI = cast(RHS);
362 }
363
364
367 if (SI == LHS) {
368 TV = simplifyBinOp(Opcode, SI->getTrueValue(), RHS, Q, MaxRecurse);
369 FV = simplifyBinOp(Opcode, SI->getFalseValue(), RHS, Q, MaxRecurse);
370 } else {
371 TV = simplifyBinOp(Opcode, LHS, SI->getTrueValue(), Q, MaxRecurse);
372 FV = simplifyBinOp(Opcode, LHS, SI->getFalseValue(), Q, MaxRecurse);
373 }
374
375
376
377 if (TV == FV)
378 return TV;
379
380
382 return FV;
384 return TV;
385
386
387
388 if (TV == SI->getTrueValue() && FV == SI->getFalseValue())
389 return SI;
390
391
392
393
394 if ((FV && !TV) || (TV && !FV)) {
395
396
397 Instruction *Simplified = dyn_cast(FV ? FV : TV);
398 if (Simplified && Simplified->getOpcode() == unsigned(Opcode) &&
399 !Simplified->hasPoisonGeneratingFlags()) {
400
401
402
403 Value *UnsimplifiedBranch = FV ? SI->getTrueValue() : SI->getFalseValue();
404 Value *UnsimplifiedLHS = SI == LHS ? UnsimplifiedBranch : LHS;
405 Value *UnsimplifiedRHS = SI == LHS ? RHS : UnsimplifiedBranch;
406 if (Simplified->getOperand(0) == UnsimplifiedLHS &&
407 Simplified->getOperand(1) == UnsimplifiedRHS)
408 return Simplified;
409 if (Simplified->isCommutative() &&
410 Simplified->getOperand(1) == UnsimplifiedLHS &&
411 Simplified->getOperand(0) == UnsimplifiedRHS)
412 return Simplified;
413 }
414 }
415
416 return nullptr;
417}
418
419
420
421
422
423
424
425
426
427
430
431 if (!MaxRecurse--)
432 return nullptr;
433
434
435 if (!isa(LHS)) {
438 }
439 assert(isa(LHS) && "Not comparing with a select instruction!");
441 Value *Cond = SI->getCondition();
442 Value *TV = SI->getTrueValue();
443 Value *FV = SI->getFalseValue();
444
445
446
448 if (!TCmp)
449 return nullptr;
450
451
453 if (!FCmp)
454 return nullptr;
455
456
457
458 if (TCmp == FCmp)
459 return TCmp;
460
461
462
465
466 return nullptr;
467}
468
469
470
471
472
475 unsigned MaxRecurse) {
476
477 if (!MaxRecurse--)
478 return nullptr;
479
481 if (isa(LHS)) {
482 PI = cast(LHS);
483
485 return nullptr;
486 } else {
487 assert(isa(RHS) && "No PHI instruction operand!");
488 PI = cast(RHS);
489
491 return nullptr;
492 }
493
494
495 Value *CommonValue = nullptr;
497
499 continue;
506
507
508 if (!V || (CommonValue && V != CommonValue))
509 return nullptr;
510 CommonValue = V;
511 }
512
513 return CommonValue;
514}
515
516
517
518
519
522
523 if (!MaxRecurse--)
524 return nullptr;
525
526
527 if (!isa(LHS)) {
530 }
531 assert(isa(LHS) && "Not comparing with a phi instruction!");
533
534
536 return nullptr;
537
538
539 Value *CommonValue = nullptr;
543
545 continue;
546
547
548
550 MaxRecurse);
551
552
553 if (!V || (CommonValue && V != CommonValue))
554 return nullptr;
555 CommonValue = V;
556 }
557
558 return CommonValue;
559}
560
564 if (auto *CLHS = dyn_cast(Op0)) {
565 if (auto *CRHS = dyn_cast(Op1)) {
566 switch (Opcode) {
567 default:
568 break;
569 case Instruction::FAdd:
570 case Instruction::FSub:
571 case Instruction::FMul:
572 case Instruction::FDiv:
573 case Instruction::FRem:
574 if (Q.CxtI != nullptr)
576 }
578 }
579
580
583 }
584 return nullptr;
585}
586
587
588
592 return C;
593
594
595 if (isa(Op1))
596 return Op1;
597
598
600 return Op1;
601
602
604 return Op0;
605
606
609
610
611
612
616 return Y;
617
618
622
623
624
625
628 return Y;
629
630
632 return Op1;
633
634
637 return V;
638
639
642 return V;
643
644
645
646
647
648
649
650
651
652
653 return nullptr;
654}
655
658 return ::simplifyAddInst(Op0, Op1, IsNSW, IsNUW, Query, RecursionLimit);
659}
660
661
662
663
664
665
666
667
668
669
671 bool AllowNonInbounds = false) {
672 assert(V->getType()->isPtrOrPtrVectorTy());
673
675 V = V->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds);
676
677
678 return Offset.sextOrTrunc(DL.getIndexTypeSizeInBits(V->getType()));
679}
680
681
682
687
688
689
691 return nullptr;
692
693
694
695
696
698 if (auto *VecTy = dyn_cast(LHS->getType()))
700 return Res;
701}
702
703
704
705
706
709
711 return nullptr;
712
713 std::optional Imp =
715 if (Imp && *Imp) {
717 switch (Opcode) {
718 case Instruction::Sub:
719 case Instruction::Xor:
720 case Instruction::URem:
721 case Instruction::SRem:
723
724 case Instruction::SDiv:
725 case Instruction::UDiv:
726 return ConstantInt::get(Ty, 1);
727
728 case Instruction::And:
729 case Instruction::Or:
730
731 return Op1;
732 default:
733 break;
734 }
735 }
736 return nullptr;
737}
738
739
740
744 return C;
745
746
747
748 if (isa(Op0) || isa(Op1))
750
751
752
755
756
758 return Op0;
759
760
761 if (Op0 == Op1)
763
764
766
767 if (IsNUW)
769
772
773
774 if (IsNSW)
776
777
778 return Op1;
779 }
780 }
781
782
783
784 Value *X = nullptr, *Y = nullptr, *Z = Op1;
786
788
789 if (Value *W = simplifyBinOp(Instruction::Add, X, V, Q, MaxRecurse - 1)) {
790
791 ++NumReassoc;
792 return W;
793 }
794
796
797 if (Value *W = simplifyBinOp(Instruction::Add, Y, V, Q, MaxRecurse - 1)) {
798
799 ++NumReassoc;
800 return W;
801 }
802 }
803
804
805
806 X = Op0;
808
810
811 if (Value *W = simplifyBinOp(Instruction::Sub, V, Z, Q, MaxRecurse - 1)) {
812
813 ++NumReassoc;
814 return W;
815 }
816
818
819 if (Value *W = simplifyBinOp(Instruction::Sub, V, Y, Q, MaxRecurse - 1)) {
820
821 ++NumReassoc;
822 return W;
823 }
824 }
825
826
827
828 Z = Op0;
830
832
833 if (Value *W = simplifyBinOp(Instruction::Add, V, Y, Q, MaxRecurse - 1)) {
834
835 ++NumReassoc;
836 return W;
837 }
838
839
842 if (X->getType() == Y->getType())
843
845
847 Q, MaxRecurse - 1))
848
849 return W;
850
851
855 Q.DL);
856
857
860 return V;
861
862
863
864
865
866
867
868
869
870
872 return V;
873
874
875 if (IsNUW) {
879 return X;
880 }
881
882 return nullptr;
883}
884
887 return ::simplifySubInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);
888}
889
890
891
895 return C;
896
897
898 if (isa(Op1))
899 return Op1;
900
901
902
905
906
908 return Op0;
909
910
916 return X;
917
919
920
921 if (IsNSW)
922 return ConstantInt::getNullValue(Op0->getType());
923
924
925 if (MaxRecurse)
927 return V;
928 }
929
930
933 return V;
934
935
937 Instruction::Add, Q, MaxRecurse))
938 return V;
939
940
941
942 if (isa(Op0) || isa(Op1))
945 return V;
946
947
948
949 if (isa(Op0) || isa(Op1))
952 return V;
953
954 return nullptr;
955}
956
959 return ::simplifyMulInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);
960}
961
962
963
964
968 Constant *C = dyn_cast_or_null(V);
969 return (C && C->isAllOnesValue());
970}
971
972
973
975 unsigned MaxRecurse, bool IsSigned) {
976
977 if (!MaxRecurse--)
978 return false;
979
980 if (IsSigned) {
981
983 return true;
984
985
986
987
988
989
990
991
995
996
997
998 Constant *PosDividendC = ConstantInt::get(Ty, C->abs());
999 Constant *NegDividendC = ConstantInt::get(Ty, -C->abs());
1002 return true;
1003 }
1005
1006
1007
1008 if (C->isMinSignedValue())
1010
1011
1012
1013
1014 Constant *PosDivisorC = ConstantInt::get(Ty, C->abs());
1015 Constant *NegDivisorC = ConstantInt::get(Ty, -C->abs());
1018 return true;
1019 }
1020 return false;
1021 }
1022
1023
1024
1025
1026
1027
1031 return true;
1032
1033
1034
1035 return isICmpTrue(ICmpInst::ICMP_ULT, X, Y, Q, MaxRecurse);
1036}
1037
1038
1039
1042 unsigned MaxRecurse) {
1043 bool IsDiv = (Opcode == Instruction::SDiv || Opcode == Instruction::UDiv);
1044 bool IsSigned = (Opcode == Instruction::SDiv || Opcode == Instruction::SRem);
1045
1047
1048
1049
1050 if (Q.isUndefValue(Op1) || isa(Op1))
1052
1053
1054
1055
1058
1059
1060
1061 if (isa(Op0))
1062 return Op0;
1063
1064
1065
1068
1069
1070
1073
1074
1075
1076 if (Op0 == Op1)
1078
1080
1081
1082
1083
1084
1087
1088
1089
1090
1091
1092
1095
1096
1097
1098
1101 auto *Mul = cast(Op0);
1102
1103
1109 }
1110 }
1111
1112 if (isDivZero(Op0, Op1, Q, MaxRecurse, IsSigned))
1114
1116 return V;
1117
1118
1119
1120 if (isa(Op0) || isa(Op1))
1122 return V;
1123
1124
1125
1126 if (isa(Op0) || isa(Op1))
1128 return V;
1129
1130 return nullptr;
1131}
1132
1133
1136 unsigned MaxRecurse) {
1138 return C;
1139
1141 return V;
1142
1143 const APInt *DivC;
1145
1146
1147
1152 }
1153
1154
1155
1156
1159 (Opcode == Instruction::UDiv
1162 return X;
1163 }
1164
1165 return nullptr;
1166}
1167
1168
1172 return C;
1173
1175 return V;
1176
1177
1179 if ((Opcode == Instruction::SRem &&
1181 (Opcode == Instruction::URem &&
1184
1185 const APInt *C0;
1187
1188
1189 if (Opcode == Instruction::SRem
1192 return C.srem(*C0).isZero();
1193 })))
1196 return C.urem(*C0).isZero();
1197 }))))
1199 }
1200 }
1201 return nullptr;
1202}
1203
1204
1205
1208
1211
1212 return simplifyDiv(Instruction::SDiv, Op0, Op1, IsExact, Q, MaxRecurse);
1213}
1214
1217 return ::simplifySDivInst(Op0, Op1, IsExact, Q, RecursionLimit);
1218}
1219
1220
1221
1224 return simplifyDiv(Instruction::UDiv, Op0, Op1, IsExact, Q, MaxRecurse);
1225}
1226
1229 return ::simplifyUDivInst(Op0, Op1, IsExact, Q, RecursionLimit);
1230}
1231
1232
1233
1235 unsigned MaxRecurse) {
1236
1237
1240 return ConstantInt::getNullValue(Op0->getType());
1241
1242
1244 return ConstantInt::getNullValue(Op0->getType());
1245
1246 return simplifyRem(Instruction::SRem, Op0, Op1, Q, MaxRecurse);
1247}
1248
1250 return ::simplifySRemInst(Op0, Op1, Q, RecursionLimit);
1251}
1252
1253
1254
1256 unsigned MaxRecurse) {
1257 return simplifyRem(Instruction::URem, Op0, Op1, Q, MaxRecurse);
1258}
1259
1261 return ::simplifyURemInst(Op0, Op1, Q, RecursionLimit);
1262}
1263
1264
1266 Constant *C = dyn_cast(Amount);
1267 if ()
1268 return false;
1269
1270
1272 return true;
1273
1274
1275
1276 const APInt *AmountC;
1278 return true;
1279
1280
1281
1283 for (unsigned I = 0,
1284 E = cast(C->getType())->getNumElements();
1287 return false;
1288 return true;
1289 }
1290
1291 return false;
1292}
1293
1294
1295
1298 unsigned MaxRecurse) {
1300 return C;
1301
1302
1303 if (isa(Op0))
1304 return Op0;
1305
1306
1309
1310
1311
1312
1316 return Op0;
1317
1318
1321
1322
1323
1324 if (isa(Op0) || isa(Op1))
1326 return V;
1327
1328
1329
1330 if (isa(Op0) || isa(Op1))
1332 return V;
1333
1334
1335
1339
1340
1341
1344 return Op0;
1345
1346
1347 if (IsNSW) {
1348 assert(Opcode == Instruction::Shl && "Expected shl for nsw instruction");
1351
1356
1359 }
1360
1361 return nullptr;
1362}
1363
1364
1365
1367 Value *Op1, bool IsExact,
1370 simplifyShift(Opcode, Op0, Op1, false, Q, MaxRecurse))
1371 return V;
1372
1373
1374 if (Op0 == Op1)
1376
1377
1378
1381
1382
1383
1384 if (IsExact) {
1386 if (Op0Known.One[0])
1387 return Op0;
1388 }
1389
1390 return nullptr;
1391}
1392
1393
1394
1398 simplifyShift(Instruction::Shl, Op0, Op1, IsNSW, Q, MaxRecurse))
1399 return V;
1400
1402
1403
1406
1407
1411 return X;
1412
1413
1415 return Op0;
1416
1417
1418
1419
1420
1421
1422 if (IsNSW && IsNUW &&
1425
1426 return nullptr;
1427}
1428
1431 return ::simplifyShlInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);
1432}
1433
1434
1435
1439 MaxRecurse))
1440 return V;
1441
1442
1445 return X;
1446
1447
1448
1449
1450
1451
1453 const APInt *ShRAmt, *ShLAmt;
1456 *ShRAmt == *ShLAmt) {
1459 if (ShRAmt->uge(EffWidthY))
1460 return X;
1461 }
1462
1463 return nullptr;
1464}
1465
1468 return ::simplifyLShrInst(Op0, Op1, IsExact, Q, RecursionLimit);
1469}
1470
1471
1472
1476 MaxRecurse))
1477 return V;
1478
1479
1480
1481
1485
1486
1489 return X;
1490
1491
1494 return Op0;
1495
1496 return nullptr;
1497}
1498
1501 return ::simplifyAShrInst(Op0, Op1, IsExact, Q, RecursionLimit);
1502}
1503
1504
1505
1507 ICmpInst *UnsignedICmp, bool IsAnd,
1510
1514 return nullptr;
1515
1517
1519
1521 if (match(UnsignedICmp,
1523 ICmpInst::isUnsigned(UnsignedPred)) {
1524
1525 if ((UnsignedPred == ICmpInst::ICMP_UGE ||
1526 UnsignedPred == ICmpInst::ICMP_ULE) &&
1527 EqPred == ICmpInst::ICMP_NE && !IsAnd)
1529
1530 if ((UnsignedPred == ICmpInst::ICMP_ULT ||
1531 UnsignedPred == ICmpInst::ICMP_UGT) &&
1532 EqPred == ICmpInst::ICMP_EQ && IsAnd)
1534
1535
1536
1537 if (EqPred == ICmpInst::ICMP_NE && (UnsignedPred == ICmpInst::ICMP_ULT ||
1538 UnsignedPred == ICmpInst::ICMP_UGT))
1539 return IsAnd ? UnsignedICmp : ZeroICmp;
1540
1541
1542
1543 if (EqPred == ICmpInst::ICMP_EQ && (UnsignedPred == ICmpInst::ICMP_ULE ||
1544 UnsignedPred == ICmpInst::ICMP_UGE))
1545 return IsAnd ? ZeroICmp : UnsignedICmp;
1546 }
1547
1548
1549
1550
1551 if (match(UnsignedICmp,
1553 if (UnsignedPred == ICmpInst::ICMP_UGE && IsAnd &&
1555 return UnsignedICmp;
1556 if (UnsignedPred == ICmpInst::ICMP_ULT && !IsAnd &&
1558 return UnsignedICmp;
1559 }
1560 }
1561
1563 ICmpInst::isUnsigned(UnsignedPred))
1564 ;
1565 else if (match(UnsignedICmp,
1567 ICmpInst::isUnsigned(UnsignedPred))
1568 UnsignedPred = ICmpInst::getSwappedPredicate(UnsignedPred);
1569 else
1570 return nullptr;
1571
1572
1573
1574 if (UnsignedPred == ICmpInst::ICMP_UGT && EqPred == ICmpInst::ICMP_EQ &&
1576 return IsAnd ? ZeroICmp : UnsignedICmp;
1577
1578
1579
1580 if (UnsignedPred == ICmpInst::ICMP_ULE && EqPred == ICmpInst::ICMP_NE &&
1582 return IsAnd ? UnsignedICmp : ZeroICmp;
1583
1584
1585
1586
1587
1588
1589
1590
1591 if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_NE)
1592 return IsAnd ? UnsignedICmp : ZeroICmp;
1593
1594
1595
1596 if (UnsignedPred == ICmpInst::ICMP_UGE && EqPred == ICmpInst::ICMP_EQ)
1597 return IsAnd ? ZeroICmp : UnsignedICmp;
1598
1599
1600 if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_EQ &&
1601 IsAnd)
1603
1604
1605 if (UnsignedPred == ICmpInst::ICMP_UGE && EqPred == ICmpInst::ICMP_NE &&
1606 !IsAnd)
1608
1609 return nullptr;
1610}
1611
1612
1613
1614
1616 bool IsAnd) {
1617
1619 return nullptr;
1620
1621 const APInt *C0, *C1;
1624 return nullptr;
1625
1628
1629
1630
1631 if (IsAnd && Range0.intersectWith(Range1).isEmptySet())
1633
1634
1635
1636 if (!IsAnd && Range0.unionWith(Range1).isFullSet())
1638
1639
1640
1641
1642
1643
1644 if (Range0.contains(Range1))
1645 return IsAnd ? Cmp1 : Cmp0;
1646 if (Range1.contains(Range0))
1647 return IsAnd ? Cmp0 : Cmp1;
1648
1649 return nullptr;
1650}
1651
1654
1656 const APInt *C0, *C1;
1659 return nullptr;
1660
1662 return nullptr;
1663
1664 auto *AddInst = cast(Op0->getOperand(0));
1665 if (AddInst->getOperand(1) != Op1->getOperand(1))
1666 return nullptr;
1667
1671
1672 const APInt Delta = *C1 - *C0;
1674 if (Delta == 2) {
1675 if (Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_SGT)
1677 if (Pred0 == ICmpInst::ICMP_SLT && Pred1 == ICmpInst::ICMP_SGT && IsNSW)
1679 }
1680 if (Delta == 1) {
1681 if (Pred0 == ICmpInst::ICMP_ULE && Pred1 == ICmpInst::ICMP_SGT)
1683 if (Pred0 == ICmpInst::ICMP_SLE && Pred1 == ICmpInst::ICMP_SGT && IsNSW)
1685 }
1686 }
1688 if (Delta == 2)
1689 if (Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_UGT)
1691 if (Delta == 1)
1692 if (Pred0 == ICmpInst::ICMP_ULE && Pred1 == ICmpInst::ICMP_UGT)
1694 }
1695
1696 return nullptr;
1697}
1698
1699
1701 bool IsAnd) {
1705 if ((Cmp0, m_ICmp(Pred0, m_IntrinsicIntrinsic::ctpop(m_Value(X)),
1708 return nullptr;
1709
1710
1711 if (!IsAnd && Pred0 == ICmpInst::ICMP_EQ && Pred1 == ICmpInst::ICMP_NE)
1712 return Cmp1;
1713
1714 if (IsAnd && Pred0 == ICmpInst::ICMP_NE && Pred1 == ICmpInst::ICMP_EQ)
1715 return Cmp1;
1716
1717 return nullptr;
1718}
1719
1723 return X;
1725 return X;
1726
1728 return X;
1729
1731 return X;
1733 return X;
1734
1736 return X;
1738 return X;
1739
1740 return nullptr;
1741}
1742
1745
1747 const APInt *C0, *C1;
1750 return nullptr;
1751
1753 return nullptr;
1754
1755 auto *AddInst = cast(Op0->getOperand(0));
1756 if (AddInst->getOperand(1) != Op1->getOperand(1))
1757 return nullptr;
1758
1762
1763 const APInt Delta = *C1 - *C0;
1765 if (Delta == 2) {
1766 if (Pred0 == ICmpInst::ICMP_UGE && Pred1 == ICmpInst::ICMP_SLE)
1768 if (Pred0 == ICmpInst::ICMP_SGE && Pred1 == ICmpInst::ICMP_SLE && IsNSW)
1770 }
1771 if (Delta == 1) {
1772 if (Pred0 == ICmpInst::ICMP_UGT && Pred1 == ICmpInst::ICMP_SLE)
1774 if (Pred0 == ICmpInst::ICMP_SGT && Pred1 == ICmpInst::ICMP_SLE && IsNSW)
1776 }
1777 }
1779 if (Delta == 2)
1780 if (Pred0 == ICmpInst::ICMP_UGE && Pred1 == ICmpInst::ICMP_ULE)
1782 if (Delta == 1)
1783 if (Pred0 == ICmpInst::ICMP_UGT && Pred1 == ICmpInst::ICMP_ULE)
1785 }
1786
1787 return nullptr;
1788}
1789
1793 return X;
1795 return X;
1796
1798 return X;
1799
1801 return X;
1803 return X;
1804
1806 return X;
1808 return X;
1809
1810 return nullptr;
1811}
1812
1814 FCmpInst *RHS, bool IsAnd) {
1815 Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);
1816 Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1);
1818 return nullptr;
1819
1822 if ((PredL == FCmpInst::FCMP_ORD || PredL == FCmpInst::FCMP_UNO) &&
1823 ((FCmpInst::isOrdered(PredR) && IsAnd) ||
1824 (FCmpInst::isUnordered(PredR) && !IsAnd))) {
1825
1826
1827
1828
1829 if ((match(RHS0, AbsOrSelfLHS0) || match(RHS1, AbsOrSelfLHS0)) &&
1831 return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)
1834 }
1835
1837 if ((PredR == FCmpInst::FCMP_ORD || PredR == FCmpInst::FCMP_UNO) &&
1838 ((FCmpInst::isOrdered(PredL) && IsAnd) ||
1839 (FCmpInst::isUnordered(PredL) && !IsAnd))) {
1840
1841
1842
1843
1844 if ((match(LHS0, AbsOrSelfRHS0) || match(LHS1, AbsOrSelfRHS0)) &&
1846 return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)
1849 }
1850
1851 return nullptr;
1852}
1853
1855 Value *Op1, bool IsAnd) {
1856
1857 auto *Cast0 = dyn_cast(Op0);
1858 auto *Cast1 = dyn_cast(Op1);
1859 if (Cast0 && Cast1 && Cast0->getOpcode() == Cast1->getOpcode() &&
1860 Cast0->getSrcTy() == Cast1->getSrcTy()) {
1861 Op0 = Cast0->getOperand(0);
1862 Op1 = Cast1->getOperand(0);
1863 }
1864
1865 Value *V = nullptr;
1866 auto *ICmp0 = dyn_cast(Op0);
1867 auto *ICmp1 = dyn_cast(Op1);
1868 if (ICmp0 && ICmp1)
1871
1872 auto *FCmp0 = dyn_cast(Op0);
1873 auto *FCmp1 = dyn_cast(Op1);
1874 if (FCmp0 && FCmp1)
1876
1877 if (!V)
1878 return nullptr;
1879 if (!Cast0)
1880 return V;
1881
1882
1883
1884 if (auto *C = dyn_cast(V))
1886 Q.DL);
1887
1888 return nullptr;
1889}
1890
1893 bool AllowRefinement,
1895 unsigned MaxRecurse);
1896
1899 unsigned MaxRecurse) {
1900 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1901 "Must be and/or");
1906 return nullptr;
1907
1908 auto Simplify = [&](Value *Res) -> Value * {
1910
1911
1912
1913
1914 if (Pred ==
1915 (Opcode == Instruction::And ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE)) {
1916 if (Res == Absorber)
1917 return Absorber;
1919 return Op0;
1920 return nullptr;
1921 }
1922
1923
1924
1925
1926 if (Res == Absorber)
1927 return Op1;
1928 return nullptr;
1929 };
1930
1931
1932
1933
1935 true,
1936 nullptr, MaxRecurse))
1937 return Simplify(Res);
1939 true,
1940 nullptr, MaxRecurse))
1941 return Simplify(Res);
1942
1943 return nullptr;
1944}
1945
1946
1947
1951 assert(BinaryOperator::isBitwiseLogicOp(Opcode) && "Expected logic op");
1959
1960
1961
1963 return Opcode == Instruction::And ? ConstantInt::getNullValue(Ty)
1964 : ConstantInt::getAllOnesValue(Ty);
1965 }
1966 }
1967 return nullptr;
1968}
1969
1970
1973 unsigned MaxRecurse) {
1974
1977
1978
1980 return Op1;
1981
1982
1986 return X;
1987
1988
1989
1990
1992 return Op1;
1993
1994
1997 return Op1;
1998
1999
2000
2004
2005
2006
2007 const APInt *Shift1, *Shift2;
2012 Shift1->uge(*Shift2))
2014
2017 return V;
2018
2019 return nullptr;
2020}
2021
2022
2023
2025 unsigned MaxRecurse) {
2027 return C;
2028
2029
2030 if (isa(Op1))
2031 return Op1;
2032
2033
2036
2037
2038 if (Op0 == Op1)
2039 return Op0;
2040
2041
2044
2045
2047 return Op0;
2048
2050 return Res;
2052 return Res;
2053
2055 return V;
2056
2057
2058 const APInt *Mask;
2059 const APInt *ShAmt;
2062
2063
2065 (~(*Mask)).lshr(*ShAmt).isZero())
2066 return Op0;
2067
2068
2069
2071 (~(*Mask)).shl(*ShAmt).isZero())
2072 return Op0;
2073 }
2074
2075
2076 const APInt *PowerC;
2081 Q.DT)) {
2083
2085 return ConstantInt::getNullValue(Op1->getType());
2086 }
2087
2089 return V;
2090
2091
2094 return V;
2095
2096
2098 Instruction::Or, Q, MaxRecurse))
2099 return V;
2100
2101
2103 Instruction::Xor, Q, MaxRecurse))
2104 return V;
2105
2106 if (isa(Op0) || isa(Op1)) {
2108
2110 return Op1;
2112 return Op0;
2113 }
2114
2115
2116
2119 return V;
2120 }
2121
2122
2123
2124 if (isa(Op0) || isa(Op1))
2127 return V;
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139 Value *XShifted;
2148 if (EffWidthY <= ShftCnt) {
2153
2154
2156 return Y;
2158 return XShifted;
2159 }
2160 }
2161
2162
2163
2170
2171 const APInt *C1;
2173
2177
2180
2181 if (*Implied == true)
2182 return Op0;
2183
2184 if (*Implied == false)
2186 }
2188
2189 if (*Implied)
2190 return Op1;
2191
2192 if (!*Implied)
2194 }
2195 }
2196
2198 return V;
2199
2200 return nullptr;
2201}
2202
2204 return ::simplifyAndInst(Op0, Op1, Q, RecursionLimit);
2205}
2206
2207
2209 assert(X->getType() == Y->getType() && "Expected same type for 'or' ops");
2211
2212
2214 return ConstantInt::getAllOnesValue(Ty);
2215
2216
2218 return ConstantInt::getAllOnesValue(Ty);
2219
2220
2222 return X;
2223
2225
2226
2227
2230 return Y;
2231
2232
2233
2236 return ConstantInt::getAllOnesValue(Ty);
2237
2238
2239
2240
2241
2244 return Y;
2245
2246
2247
2248
2249
2252 return X;
2253
2254
2255
2256
2257
2260 return ConstantInt::getAllOnesValue(Ty);
2261
2262
2263
2264
2265
2270 return NotA;
2271
2272
2273
2277 return NotA;
2278
2279
2280
2285 return NotAB;
2286
2287
2288
2292 return NotAB;
2293
2294 return nullptr;
2295}
2296
2297
2298
2300 unsigned MaxRecurse) {
2302 return C;
2303
2304
2305 if (isa(Op1))
2306 return Op1;
2307
2308
2309
2310
2313
2314
2315
2317 return Op0;
2318
2320 return R;
2322 return R;
2323
2325 return V;
2326
2327
2328
2329
2330
2339 C->ule(X->getType()->getScalarSizeInBits())) {
2340 return ConstantInt::getAllOnesValue(X->getType());
2341 }
2342 }
2343
2344
2345
2346
2347
2348
2352 return Op0;
2356 return Op1;
2357
2358
2359
2363 return Op0;
2367 return Op1;
2368
2371 return V;
2374 return V;
2375
2377 return V;
2378
2379
2380
2381
2383 return Op1;
2385 return Op0;
2386
2387
2390 return V;
2391
2392
2394 Instruction::And, Q, MaxRecurse))
2395 return V;
2396
2397 if (isa(Op0) || isa(Op1)) {
2399
2401 return Op1;
2403 return Op0;
2404 }
2405
2406
2407
2410 return V;
2411 }
2412
2413
2415 const APInt *C1, *C2;
2418 if (*C1 == ~*C2) {
2419
2420
2421
2422
2424 if (C2->isMask() &&
2426
2428 return A;
2429 }
2430
2432
2434 return B;
2435 }
2436 }
2437 }
2438
2439
2440
2441 if (isa(Op0) || isa(Op1))
2443 return V;
2444
2445
2449
2451 if (std::optional Implied =
2453
2454 if (*Implied == false)
2455 return Op0;
2456
2457 if (*Implied == true)
2459 }
2460 if (std::optional Implied =
2462
2463 if (*Implied == false)
2464 return Op1;
2465
2466 if (*Implied == true)
2468 }
2469 }
2470
2472 return V;
2473
2474 return nullptr;
2475}
2476
2478 return ::simplifyOrInst(Op0, Op1, Q, RecursionLimit);
2479}
2480
2481
2482
2484 unsigned MaxRecurse) {
2486 return C;
2487
2488
2489 if (isa(Op1))
2490 return Op1;
2491
2492
2494 return Op1;
2495
2496
2498 return Op0;
2499
2500
2501 if (Op0 == Op1)
2503
2504
2507
2510
2513 return A;
2514
2515
2516
2517
2522 return NotA;
2523
2524 return nullptr;
2525 };
2526 if (Value *R = foldAndOrNot(Op0, Op1))
2527 return R;
2528 if (Value *R = foldAndOrNot(Op1, Op0))
2529 return R;
2530
2532 return V;
2533
2534
2537 return V;
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2549 return V;
2550
2551
2552 {
2556 return X;
2557 }
2558
2559 return nullptr;
2560}
2561
2563 return ::simplifyXorInst(Op0, Op1, Q, RecursionLimit);
2564}
2565
2568}
2569
2570
2571
2572
2575 SelectInst *SI = dyn_cast(V);
2576 if (!SI)
2577 return nullptr;
2578 CmpInst *Cmp = dyn_cast(SI->getCondition());
2579 if (!Cmp)
2580 return nullptr;
2581 Value *CmpLHS = Cmp->getOperand(0), *CmpRHS = Cmp->getOperand(1);
2582 if (Pred == Cmp->getPredicate() && LHS == CmpLHS && RHS == CmpRHS)
2583 return Cmp;
2585 LHS == CmpRHS && RHS == CmpLHS)
2586 return Cmp;
2587 return nullptr;
2588}
2589
2590
2591
2593
2594
2595
2596
2597
2598 if (const AllocaInst *AI = dyn_cast(V))
2599 return AI->isStaticAlloca();
2600 if (const GlobalValue *GV = dyn_cast(V))
2601 return (GV->hasLocalLinkage() || GV->hasHiddenVisibility() ||
2602 GV->hasProtectedVisibility() || GV->hasGlobalUnnamedAddr()) &&
2603 !GV->isThreadLocal();
2604 if (const Argument *A = dyn_cast(V))
2605 return A->hasByValAttr();
2606 return false;
2607}
2608
2609
2610
2611
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638 auto isByValArg = [](const Value *V) {
2639 const Argument *A = dyn_cast(V);
2640 return A && A->hasByValAttr();
2641 };
2642
2643
2644
2645 if (isByValArg(V1))
2646 return isa(V2) || isa(V2) || isByValArg(V2);
2647 if (isByValArg(V2))
2648 return isa(V1) || isa(V1) || isByValArg(V1);
2649
2650 return isa(V1) &&
2651 (isa(V2) || isa(V2));
2652}
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2687
2688
2689 switch (Pred) {
2690 default:
2691 return nullptr;
2692
2693
2696 break;
2697
2698
2699
2704
2705
2707 break;
2708 }
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2720 unsigned IndexSize = DL.getIndexTypeSizeInBits(LHS->getType());
2721 APInt LHSOffset(IndexSize, 0), RHSOffset(IndexSize, 0);
2724
2725
2726
2730
2731
2733
2734
2735
2736
2737
2741 Opts.EvalMode = ObjectSizeOpts::Mode::Min;
2743 if (auto *I = dyn_cast(V))
2744 return I->getFunction();
2745 if (auto *A = dyn_cast(V))
2746 return A->getParent();
2747 return nullptr;
2752 APInt Dist = LHSOffset - RHSOffset;
2753 if (Dist.isNonNegative() ? Dist.ult(LHSSize) : (-Dist).ult(RHSSize))
2756 }
2757 }
2758
2759
2760
2761
2762
2763
2767
2768
2771 };
2772
2773
2774
2775
2778 };
2779
2780 if ((IsNAC(LHSUObjs) && IsAllocDisjoint(RHSUObjs)) ||
2781 (IsNAC(RHSUObjs) && IsAllocDisjoint(LHSUObjs)))
2784
2785
2786
2787
2788
2789
2795 if (MI) {
2796
2797
2798
2799
2800 struct CustomCaptureTracker : public CaptureTracker {
2801 bool Captured = false;
2802 void tooManyUses() override { Captured = true; }
2804 if (auto *ICmp = dyn_cast(U->getUser())) {
2805
2806
2807
2808 unsigned OtherIdx = 1 - U->getOperandNo();
2809 auto *LI = dyn_cast(ICmp->getOperand(OtherIdx));
2810 if (LI && isa(LI->getPointerOperand()))
2811 return false;
2812 }
2813
2814 Captured = true;
2815 return true;
2816 }
2817 };
2818 CustomCaptureTracker Tracker;
2820 if (!Tracker.Captured)
2823 }
2824 }
2825
2826
2827 return nullptr;
2828}
2829
2830
2836 return nullptr;
2837
2838
2839
2840
2841
2842 auto ExtractNotLHS = [](Value *V) -> Value * {
2845 return X;
2846 return nullptr;
2847 };
2848
2850 switch (Pred) {
2854 return LHS;
2855
2859 if (Value *X = ExtractNotLHS(LHS))
2860 return X;
2861 break;
2862
2866
2870
2871 default:
2872 break;
2873 }
2875 switch (Pred) {
2879 return LHS;
2880
2884 if (Value *X = ExtractNotLHS(LHS))
2885 return X;
2886 break;
2887
2891
2895
2896 default:
2897 break;
2898 }
2899 }
2900
2901 switch (Pred) {
2902 default:
2903 break;
2904 case ICmpInst::ICMP_UGE:
2907 break;
2908 case ICmpInst::ICMP_SGE:
2909
2910
2911
2912
2913
2914
2915
2918 break;
2919 case ICmpInst::ICMP_ULE:
2922 break;
2923 case ICmpInst::ICMP_SLE:
2924
2927 break;
2928 }
2929
2930 return nullptr;
2931}
2932
2933
2937 return nullptr;
2938
2940 switch (Pred) {
2941 default:
2943 case ICmpInst::ICMP_ULT:
2945 case ICmpInst::ICMP_UGE:
2947 case ICmpInst::ICMP_EQ:
2948 case ICmpInst::ICMP_ULE:
2951 break;
2952 case ICmpInst::ICMP_NE:
2953 case ICmpInst::ICMP_UGT:
2956 break;
2957 case ICmpInst::ICMP_SLT: {
2963 break;
2964 }
2965 case ICmpInst::ICMP_SLE: {
2971 break;
2972 }
2973 case ICmpInst::ICMP_SGE: {
2979 break;
2980 }
2981 case ICmpInst::ICMP_SGT: {
2987 break;
2988 }
2989 }
2990
2991 return nullptr;
2992}
2993
2997
3001 return nullptr;
3002
3003
3004
3005
3006
3008 bool TrueIfSigned;
3011 }
3012
3013
3019
3023 if (RHS_CR.contains(LHS_CR))
3027 }
3028
3029
3030
3031 const APInt *MulC;
3034 *MulC != 0 && C->urem(*MulC) != 0) ||
3036 *MulC != 0 && C->srem(*MulC) != 0)))
3037 return ConstantInt::get(ITy, Pred == ICmpInst::ICMP_NE);
3038
3039 return nullptr;
3040}
3041
3043
3044
3047 if (!Res.insert(V).second)
3048 return;
3049
3050
3051 if (++Depth > 1)
3052 return;
3053
3054 auto *I = dyn_cast(V);
3055 if ()
3056 return;
3057
3064 }
3065 } else {
3067 switch (I->getOpcode()) {
3068 case Instruction::And:
3071 break;
3072 case Instruction::URem:
3073 case Instruction::UDiv:
3074 case Instruction::LShr:
3076 break;
3077 case Instruction::Call:
3078 if (match(I, m_IntrinsicIntrinsic::usub\_sat(m_Value(X))))
3080 break;
3081 default:
3082 break;
3083 }
3084 }
3085}
3086
3089 if (Pred != ICmpInst::ICMP_UGE && Pred != ICmpInst::ICMP_ULT)
3090 return nullptr;
3091
3092
3093
3098 for (Value *GV : GreaterValues)
3099 if (LowerValues.contains(GV))
3101 Pred == ICmpInst::ICMP_UGE);
3102 return nullptr;
3103}
3104
3107 unsigned MaxRecurse) {
3109
3111
3113 if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) {
3117 return Pred == ICmpInst::ICMP_SLT ? getTrue(ITy) : getFalse(ITy);
3119 return Pred == ICmpInst::ICMP_SLT ? getFalse(ITy) : getTrue(ITy);
3120 }
3121 }
3122
3123
3125 switch (Pred) {
3126 default:
3127 break;
3128 case ICmpInst::ICMP_SGT:
3129 case ICmpInst::ICMP_SGE: {
3132 break;
3133 [[fallthrough]];
3134 }
3135 case ICmpInst::ICMP_EQ:
3136 case ICmpInst::ICMP_UGT:
3137 case ICmpInst::ICMP_UGE:
3139 case ICmpInst::ICMP_SLT:
3140 case ICmpInst::ICMP_SLE: {
3143 break;
3144 [[fallthrough]];
3145 }
3146 case ICmpInst::ICMP_NE:
3147 case ICmpInst::ICMP_ULT:
3148 case ICmpInst::ICMP_ULE:
3150 }
3151 }
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3167 switch (Pred) {
3168 default:
3169 break;
3170 case ICmpInst::ICMP_EQ:
3171 case ICmpInst::ICMP_UGE:
3172 case ICmpInst::ICMP_UGT:
3174 case ICmpInst::ICMP_NE:
3175 case ICmpInst::ICMP_ULT:
3176 case ICmpInst::ICMP_ULE:
3178 }
3179 }
3180 }
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191 const APInt *C1, *C2;
3193 C1->ule(*C2)) ||
3198 if (Pred == ICmpInst::ICMP_UGT)
3200 if (Pred == ICmpInst::ICMP_ULE)
3202 }
3203
3204
3205
3208 return (Pred == ICmpInst::ICMP_EQ) ? getFalse(ITy) : getTrue(ITy);
3209
3210 return nullptr;
3211}
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3227
3229 return false;
3230
3231
3235 return false;
3236
3238 const APInt *C1, *C2;
3241 return false;
3242
3245}
3246
3247
3248
3249
3252 unsigned MaxRecurse) {
3255 if (MaxRecurse && (LBO || RBO)) {
3256
3257 Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr;
3258
3259 bool NoLHSWrapProblem = false, NoRHSWrapProblem = false;
3260 if (LBO && LBO->getOpcode() == Instruction::Add) {
3263 NoLHSWrapProblem =
3269 }
3270 if (RBO && RBO->getOpcode() == Instruction::Add) {
3273 NoRHSWrapProblem =
3279 }
3280
3281
3282 if ((A == RHS || B == RHS) && NoLHSWrapProblem)
3285 MaxRecurse - 1))
3286 return V;
3287
3288
3289 if ((C == LHS || D == LHS) && NoRHSWrapProblem)
3292 C == LHS ? D : C, Q, MaxRecurse - 1))
3293 return V;
3294
3295
3296 bool CanSimplify = (NoLHSWrapProblem && NoRHSWrapProblem) ||
3298 if (A && C && (A == C || A == D || B == C || B == D) && CanSimplify) {
3299
3302
3304 Z = D;
3306
3308 Z = C;
3310
3312 Z = D;
3313 } else {
3315
3317 Z = C;
3318 }
3320 return V;
3321 }
3322 }
3323
3324 if (LBO)
3326 return V;
3327
3328 if (RBO)
3330 ICmpInst::getSwappedPredicate(Pred), RBO, LHS, Q, MaxRecurse))
3331 return V;
3332
3333
3337 if (C->isStrictlyPositive()) {
3338 if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_NE)
3340 if (Pred == ICmpInst::ICMP_SGE || Pred == ICmpInst::ICMP_EQ)
3342 }
3343 if (C->isNonNegative()) {
3344 if (Pred == ICmpInst::ICMP_SLE)
3346 if (Pred == ICmpInst::ICMP_SGT)
3348 }
3349 }
3350 }
3351
3352
3353
3354
3358
3359
3360
3361
3362
3363
3364
3365
3369 if (Pred == ICmpInst::ICMP_EQ)
3371 if (Pred == ICmpInst::ICMP_NE)
3373 }
3374 }
3375
3376
3377
3378
3380 if (Pred == ICmpInst::ICMP_UGT)
3382 if (Pred == ICmpInst::ICMP_ULE)
3384 }
3385
3386 if (!MaxRecurse || !LBO || !RBO || LBO->getOpcode() != RBO->getOpcode())
3387 return nullptr;
3388
3391 default:
3392 break;
3393 case Instruction::Shl: {
3396 if (!NUW || (ICmpInst::isSigned(Pred) && !NSW) ||
3398 break;
3400 RBO->getOperand(1), Q, MaxRecurse - 1))
3401 return V;
3402 break;
3403 }
3404
3405
3406
3407
3408
3409 case Instruction::And:
3410 case Instruction::Or: {
3411 const APInt *C1, *C2;
3417 Pred = ICmpInst::getSwappedPredicate(Pred);
3418 }
3420 if (Pred == ICmpInst::ICMP_ULE)
3422 if (Pred == ICmpInst::ICMP_UGT)
3425 if (Pred == ICmpInst::ICMP_SLE)
3427 if (Pred == ICmpInst::ICMP_SGT)
3429 }
3430 }
3431 }
3432 break;
3433 }
3434 }
3435 }
3436
3439 default:
3440 break;
3441 case Instruction::UDiv:
3442 case Instruction::LShr:
3443 if (ICmpInst::isSigned(Pred) || !Q.IIQ.isExact(LBO) ||
3445 break;
3447 RBO->getOperand(0), Q, MaxRecurse - 1))
3448 return V;
3449 break;
3450 case Instruction::SDiv:
3453 break;
3455 RBO->getOperand(0), Q, MaxRecurse - 1))
3456 return V;
3457 break;
3458 case Instruction::AShr:
3460 break;
3462 RBO->getOperand(0), Q, MaxRecurse - 1))
3463 return V;
3464 break;
3465 case Instruction::Shl: {
3468 if (!NUW && !NSW)
3469 break;
3470 if (!NSW && ICmpInst::isSigned(Pred))
3471 break;
3473 RBO->getOperand(0), Q, MaxRecurse - 1))
3474 return V;
3475 break;
3476 }
3477 }
3478 }
3479 return nullptr;
3480}
3481
3482
3483
3486 unsigned MaxRecurse) {
3490 CmpInst::Predicate EqP;
3491
3492
3497
3498 P = Pred;
3504
3511
3512
3519
3520
3521 P = Pred;
3522 }
3524
3525 switch (P) {
3526 default:
3527 break;
3530
3531
3533 return V;
3535 return V;
3536
3537 if (MaxRecurse)
3539 return V;
3540 break;
3544
3545
3547 return V;
3549 return V;
3550
3551 if (MaxRecurse)
3553 return V;
3554 break;
3555 }
3557
3560
3562 }
3563 }
3564
3565
3571
3572 P = Pred;
3578
3585
3586
3593
3594
3595 P = Pred;
3596 }
3598
3599 switch (P) {
3600 default:
3601 break;
3604
3605
3607 return V;
3609 return V;
3610
3611 if (MaxRecurse)
3613 return V;
3614 break;
3618
3619
3621 return V;
3623 return V;
3624
3625 if (MaxRecurse)
3627 return V;
3628 break;
3629 }
3634 }
3635 }
3636
3637
3638
3642 Pred = ICmpInst::getSwappedPredicate(Pred);
3643 }
3644
3648 (A == C || A == D || B == C || B == D)) {
3649
3652
3657 (A == C || A == D || B == C || B == D)) {
3658
3661
3664 }
3665
3666 return nullptr;
3667}
3668
3672
3674 return nullptr;
3675
3676 for (Value *AssumeBaseOp : {LHS, RHS}) {
3678 if (!AssumeVH)
3679 continue;
3680
3681 CallInst *Assume = cast(AssumeVH);
3683 Assume->getArgOperand(0), Predicate, LHS, RHS, Q.DL))
3686 }
3687 }
3688
3689 return nullptr;
3690}
3691
3694 auto *II = dyn_cast(LHS);
3695 if ()
3696 return nullptr;
3697
3698 switch (II->getIntrinsicID()) {
3699 case Intrinsic::uadd_sat:
3700
3703 if (Pred == ICmpInst::ICMP_UGE)
3705 if (Pred == ICmpInst::ICMP_ULT)
3707 }
3708 return nullptr;
3709 case Intrinsic::usub_sat:
3710
3713 if (Pred == ICmpInst::ICMP_ULE)
3715 if (Pred == ICmpInst::ICMP_UGT)
3717 }
3718 return nullptr;
3719 default:
3720 return nullptr;
3721 }
3722}
3723
3724
3727 if (Instruction *I = dyn_cast(V))
3730
3731 if (const Argument *A = dyn_cast(V))
3732 return A->getRange();
3733 else if (const CallBase *CB = dyn_cast(V))
3734 return CB->getRange();
3735
3736 return std::nullopt;
3737}
3738
3739
3740
3744
3745 if (Constant *CLHS = dyn_cast(LHS)) {
3746 if (Constant *CRHS = dyn_cast(RHS))
3748
3749
3752 }
3753 assert(!isa(LHS) && "Unexpected icmp undef,%X");
3754
3756
3757
3758 if (isa(RHS))
3760
3761
3762
3763
3766
3767
3768
3771
3773 return V;
3774
3775
3776
3778 return V;
3779
3781 return V;
3782
3783
3784
3785 if (std::optional RhsCr = getRange(RHS, Q.IIQ))
3786 if (std::optional LhsCr = getRange(LHS, Q.IIQ)) {
3787 if (LhsCr->icmp(Pred, *RhsCr))
3789
3792 }
3793
3794
3795 if (isa(LHS) && (isa(RHS) || isa(RHS))) {
3800
3801
3802
3803 if (MaxRecurse && isa(LI) &&
3805 if (Constant *RHSC = dyn_cast(RHS)) {
3806
3809 Q, MaxRecurse - 1))
3810 return V;
3811 } else if (PtrToIntInst *RI = dyn_cast(RHS)) {
3812 if (RI->getOperand(0)->getType() == SrcTy)
3813
3815 MaxRecurse - 1))
3816 return V;
3817 }
3818 }
3819
3820 if (isa(LHS)) {
3821
3822
3823 if (ZExtInst *RI = dyn_cast(RHS)) {
3824 if (MaxRecurse && SrcTy == RI->getOperand(0)->getType())
3825
3828 RI->getOperand(0), Q, MaxRecurse - 1))
3829 return V;
3830 }
3831
3832 else if (SExtInst *RI = dyn_cast(RHS)) {
3833 if (SrcOp == RI->getOperand(0)) {
3834 if (Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_SGE)
3836 if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SLT)
3838 }
3839 }
3840
3841
3845
3846
3847
3850 assert(Trunc && "Constant-fold of ImmConstant should not fail");
3853 assert(RExt && "Constant-fold of ImmConstant should not fail");
3856 assert(AnyEq && "Constant-fold of ImmConstant should not fail");
3857
3858
3859
3860
3863 SrcOp, Trunc, Q, MaxRecurse - 1))
3864 return V;
3865
3866
3867
3869 switch (Pred) {
3870 default:
3872
3873 case ICmpInst::ICMP_EQ:
3874 case ICmpInst::ICMP_UGT:
3875 case ICmpInst::ICMP_UGE:
3877
3878 case ICmpInst::ICMP_NE:
3879 case ICmpInst::ICMP_ULT:
3880 case ICmpInst::ICMP_ULE:
3882
3883
3884
3885 case ICmpInst::ICMP_SGT:
3886 case ICmpInst::ICMP_SGE:
3889 Q.DL);
3890 case ICmpInst::ICMP_SLT:
3891 case ICmpInst::ICMP_SLE:
3894 Q.DL);
3895 }
3896 }
3897 }
3898 }
3899
3900 if (isa(LHS)) {
3901
3902
3903 if (SExtInst *RI = dyn_cast(RHS)) {
3904 if (MaxRecurse && SrcTy == RI->getOperand(0)->getType())
3905
3907 MaxRecurse - 1))
3908 return V;
3909 }
3910
3911 else if (ZExtInst *RI = dyn_cast(RHS)) {
3912 if (SrcOp == RI->getOperand(0)) {
3913 if (Pred == ICmpInst::ICMP_UGE || Pred == ICmpInst::ICMP_SLE)
3915 if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SGT)
3917 }
3918 }
3919
3920
3923
3924
3925
3928 assert(Trunc && "Constant-fold of ImmConstant should not fail");
3931 assert(RExt && "Constant-fold of ImmConstant should not fail");
3934 assert(AnyEq && "Constant-fold of ImmConstant should not fail");
3935
3936
3937
3941 return V;
3942
3943
3944
3946 switch (Pred) {
3947 default:
3949 case ICmpInst::ICMP_EQ:
3951 case ICmpInst::ICMP_NE:
3953
3954
3955
3956 case ICmpInst::ICMP_SGT:
3957 case ICmpInst::ICMP_SGE:
3960 Q.DL);
3961 case ICmpInst::ICMP_SLT:
3962 case ICmpInst::ICMP_SLE:
3965 Q.DL);
3966
3967
3968
3969 case ICmpInst::ICMP_UGT:
3970 case ICmpInst::ICMP_UGE:
3971
3972 if (MaxRecurse)
3975 MaxRecurse - 1))
3976 return V;
3977 break;
3978 case ICmpInst::ICMP_ULT:
3979 case ICmpInst::ICMP_ULE:
3980
3981 if (MaxRecurse)
3984 MaxRecurse - 1))
3985 return V;
3986 break;
3987 }
3988 }
3989 }
3990 }
3991 }
3992
3993
3994
3995
3998 return Pred == ICmpInst::ICMP_NE ? getTrue(ITy) : getFalse(ITy);
3999 }
4000
4002 return V;
4003
4005 return V;
4006
4008 return V;
4010 ICmpInst::getSwappedPredicate(Pred), RHS, LHS))
4011 return V;
4012
4014 return V;
4016 ICmpInst::getSwappedPredicate(Pred), RHS, LHS))
4017 return V;
4018
4020 return V;
4021
4022 if (std::optional Res =
4025
4026
4027
4030 return C;
4031 if (auto *CLHS = dyn_cast(LHS))
4032 if (auto *CRHS = dyn_cast(RHS))
4033 if (CLHS->getPointerOperandType() == CRHS->getPointerOperandType() &&
4037 CRHS->getPointerOperand(), Q))
4038 return C;
4039
4040
4041
4042 if (isa(LHS) || isa(RHS))
4044 return V;
4045
4046
4047
4048 if (isa(LHS) || isa(RHS))
4050 return V;
4051
4052 return nullptr;
4053}
4054
4058}
4059
4060
4061
4064 unsigned MaxRecurse) {
4066
4067 if (Constant *CLHS = dyn_cast(LHS)) {
4068 if (Constant *CRHS = dyn_cast(RHS))
4071
4072
4075 }
4076
4077
4079 if (Pred == FCmpInst::FCMP_FALSE)
4081 if (Pred == FCmpInst::FCMP_TRUE)
4083
4084
4085
4086 if (isa(LHS) || isa(RHS))
4088
4089
4090
4092
4093
4095 }
4096
4097
4103 }
4104
4105
4106
4107
4108
4109 if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO) {
4114
4117 return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD);
4118
4121 }
4122
4125 std::optional FullKnownClassLHS;
4126
4127
4128
4129 auto computeLHSClass = [=, &FullKnownClassLHS](FPClassTest InterestedFlags =
4131 if (FullKnownClassLHS)
4132 return *FullKnownClassLHS;
4134 };
4135
4137
4138
4139
4140
4141
4144 if (ClassVal) {
4145 FullKnownClassLHS = computeLHSClass();
4146 if ((FullKnownClassLHS->KnownFPClasses & ClassTest) == fcNone)
4148 if ((FullKnownClassLHS->KnownFPClasses & ~ClassTest) == fcNone)
4150 }
4151 }
4152
4153
4154 if (C) {
4155
4156
4157 if (C->isNaN())
4159
4160
4161
4162
4163 if (C->isNegative() && ->isNegZero()) {
4165
4166
4167
4168 switch (Pred) {
4169 case FCmpInst::FCMP_UGE:
4170 case FCmpInst::FCMP_UGT:
4171 case FCmpInst::FCMP_UNE: {
4172 KnownFPClass KnownClass = computeLHSClass(Interested);
4173
4174
4177 break;
4178 }
4179 case FCmpInst::FCMP_OEQ:
4180 case FCmpInst::FCMP_OLE:
4181 case FCmpInst::FCMP_OLT: {
4182 KnownFPClass KnownClass = computeLHSClass(Interested);
4183
4184
4187 break;
4188 }
4189 default:
4190 break;
4191 }
4192 }
4193
4196 *C2 < *C) ||
4198 *C2 > *C)) {
4199 bool IsMaxNum =
4200 cast(LHS)->getIntrinsicID() == Intrinsic::maxnum;
4201
4202
4203 switch (Pred) {
4204 case FCmpInst::FCMP_OEQ:
4205 case FCmpInst::FCMP_UEQ:
4206
4207
4209 case FCmpInst::FCMP_ONE:
4210 case FCmpInst::FCMP_UNE:
4211
4212
4214 case FCmpInst::FCMP_OGE:
4215 case FCmpInst::FCMP_UGE:
4216 case FCmpInst::FCMP_OGT:
4217 case FCmpInst::FCMP_UGT:
4218
4219
4220
4221
4222 return ConstantInt::get(RetTy, IsMaxNum);
4223 case FCmpInst::FCMP_OLE:
4224 case FCmpInst::FCMP_ULE:
4225 case FCmpInst::FCMP_OLT:
4226 case FCmpInst::FCMP_ULT:
4227
4228
4229
4230
4231 return ConstantInt::get(RetTy, !IsMaxNum);
4232 default:
4233
4235 }
4236 }
4237 }
4238
4239
4240
4242 switch (Pred) {
4243 case FCmpInst::FCMP_OGE:
4244 case FCmpInst::FCMP_ULT: {
4247 Interested |= fcNan;
4248
4249 KnownFPClass Known = computeLHSClass(Interested);
4250
4251
4252
4256 break;
4257 }
4258 case FCmpInst::FCMP_UGE:
4259 case FCmpInst::FCMP_OLT: {
4261 KnownFPClass Known = computeLHSClass(Interested);
4262
4263
4264
4267 break;
4268 }
4269 default:
4270 break;
4271 }
4272 }
4273
4274
4275
4276 if (isa(LHS) || isa(RHS))
4278 return V;
4279
4280
4281
4282 if (isa(LHS) || isa(RHS))
4284 return V;
4285
4286 return nullptr;
4287}
4288
4292}
4293
4295 ArrayRef<std::pair<Value *, Value *>> Ops,
4297 bool AllowRefinement,
4299 unsigned MaxRecurse) {
4301 "If AllowRefinement=false then CanUseUndef=false");
4302 for (const auto &OpAndRepOp : Ops) {
4303
4304 if (isa(OpAndRepOp.first))
4305 return nullptr;
4306
4307
4308 if (V == OpAndRepOp.first)
4309 return OpAndRepOp.second;
4310 }
4311
4312 if (!MaxRecurse--)
4313 return nullptr;
4314
4315 auto *I = dyn_cast(V);
4316 if ()
4317 return nullptr;
4318
4319
4320
4321 if (isa(I))
4322 return nullptr;
4323
4324
4325 if (match(I, m_IntrinsicIntrinsic::is\_constant()))
4326 return nullptr;
4327
4328
4329 if (isa(I))
4330 return nullptr;
4331
4332 for (const auto &OpAndRepOp : Ops) {
4333
4334
4335 if (OpAndRepOp.first->getType()->isVectorTy() &&
4337 return nullptr;
4338 }
4339
4340
4342 bool AnyReplaced = false;
4343 for (Value *InstOp : I->operands()) {
4345 InstOp, Ops, Q, AllowRefinement, DropFlags, MaxRecurse)) {
4347 AnyReplaced = InstOp != NewInstOp;
4348 } else {
4350 }
4351
4352
4353
4355 return nullptr;
4356 }
4357
4358 if (!AnyReplaced)
4359 return nullptr;
4360
4361 if (!AllowRefinement) {
4362
4363
4364
4365
4366 if (auto *BO = dyn_cast(I)) {
4367 unsigned Opcode = BO->getOpcode();
4368
4369
4370 if (!BO->getType()->isFPOrFPVectorTy()) {
4372 return NewOps[1];
4374 true))
4375 return NewOps[0];
4376 }
4377
4378
4379 if ((Opcode == Instruction::And || Opcode == Instruction::Or) &&
4380 NewOps[0] == NewOps[1]) {
4381
4382 if (auto *PDI = dyn_cast(BO)) {
4383 if (PDI->isDisjoint()) {
4384 if (!DropFlags)
4385 return nullptr;
4387 }
4388 }
4389 return NewOps[0];
4390 }
4391
4392
4393
4394
4395 if ((Opcode == Instruction::Sub || Opcode == Instruction::Xor) &&
4396 NewOps[0] == NewOps[1] &&
4397 any_of(Ops, [=](const auto &Rep) { return NewOps[0] == Rep.second; }))
4399
4400
4401
4402
4403
4404
4405
4406
4408 if ((NewOps[0] == Absorber || NewOps[1] == Absorber) &&
4410 [=](const auto &Rep) { return impliesPoison(BO, Rep.first); }))
4411 return Absorber;
4412 }
4413
4414 if (isa(I)) {
4415
4416
4418 return NewOps[0];
4419 }
4420 } else {
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430 auto PreventSelfSimplify = [V](Value *Simplified) {
4431 return Simplified != V ? Simplified : nullptr;
4432 };
4433
4434 return PreventSelfSimplify(
4436 }
4437
4438
4439
4441 for (Value *NewOp : NewOps) {
4442 if (Constant *ConstOp = dyn_cast(NewOp))
4444 else
4445 return nullptr;
4446 }
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457 if (!AllowRefinement) {
4459
4460 if (auto *II = dyn_cast(I);
4461 II && II->getIntrinsicID() == Intrinsic::abs) {
4462 if (!ConstOps[0]->isNotMinSignedValue())
4463 return nullptr;
4464 } else
4465 return nullptr;
4466 }
4468 false);
4469 if (DropFlags && Res && I->hasPoisonGeneratingAnnotations())
4471 return Res;
4472 }
4473
4475 false);
4476}
4477
4480 bool AllowRefinement,
4482 unsigned MaxRecurse) {
4484 DropFlags, MaxRecurse);
4485}
4486
4489 bool AllowRefinement,
4491
4492
4493 if (!AllowRefinement)
4494 return ::simplifyWithOpReplaced(V, Op, RepOp, Q.getWithoutUndef(),
4496 return ::simplifyWithOpReplaced(V, Op, RepOp, Q, AllowRefinement, DropFlags,
4498}
4499
4500
4501
4503 const APInt *Y, bool TrueWhenUnset) {
4505
4506
4507
4510 return TrueWhenUnset ? FalseVal : TrueVal;
4511
4512
4513
4516 return TrueWhenUnset ? FalseVal : TrueVal;
4517
4518 if (Y->isPowerOf2()) {
4519
4520
4523
4524 if (TrueWhenUnset && cast(TrueVal)->isDisjoint())
4525 return nullptr;
4526 return TrueWhenUnset ? TrueVal : FalseVal;
4527 }
4528
4529
4530
4533
4534 if (!TrueWhenUnset && cast(FalseVal)->isDisjoint())
4535 return nullptr;
4536 return TrueWhenUnset ? TrueVal : FalseVal;
4537 }
4538 }
4539
4540 return nullptr;
4541}
4542
4546
4547 if (CmpRHS == TVal || CmpRHS == FVal) {
4549 Pred = ICmpInst::getSwappedPredicate(Pred);
4550 }
4551
4552
4553 if (CmpLHS == FVal) {
4555 Pred = ICmpInst::getInversePredicate(Pred);
4556 }
4557
4558
4559
4560 Value *X = CmpLHS, *Y = CmpRHS;
4561 bool PeekedThroughSelectShuffle = false;
4562 auto *Shuf = dyn_cast(FVal);
4563 if (Shuf && Shuf->isSelect()) {
4564 if (Shuf->getOperand(0) == Y)
4565 FVal = Shuf->getOperand(1);
4566 else if (Shuf->getOperand(1) == Y)
4567 FVal = Shuf->getOperand(0);
4568 else
4569 return nullptr;
4570 PeekedThroughSelectShuffle = true;
4571 }
4572
4573
4574 auto *MMI = dyn_cast(FVal);
4575 if (!MMI || TVal != X ||
4577 return nullptr;
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4590 return MMI;
4591
4592
4593 if (PeekedThroughSelectShuffle)
4594 return nullptr;
4595
4596
4598 return MMI;
4599
4600
4602 return X;
4603
4604
4605
4606
4607
4610 return X;
4611
4612 return nullptr;
4613}
4614
4615
4616
4619 Value *FalseVal) {
4622 Res->Pred == ICmpInst::ICMP_EQ);
4623
4624 return nullptr;
4625}
4626
4627
4628
4630 ArrayRef<std::pair<Value *, Value *>> Replacements, Value *TrueVal,
4632 Value *SimplifiedFalseVal =
4634 false,
4635 nullptr, MaxRecurse);
4636 if (!SimplifiedFalseVal)
4637 SimplifiedFalseVal = FalseVal;
4638
4639 Value *SimplifiedTrueVal =
4641 true,
4642 nullptr, MaxRecurse);
4643 if (!SimplifiedTrueVal)
4644 SimplifiedTrueVal = TrueVal;
4645
4646 if (SimplifiedFalseVal == SimplifiedTrueVal)
4647 return FalseVal;
4648
4649 return nullptr;
4650}
4651
4652
4653
4655 Value *FalseVal,
4657 unsigned MaxRecurse) {
4659 Value *CmpLHS, *CmpRHS;
4661 return nullptr;
4662
4664 return V;
4665
4666
4667 if (Pred == ICmpInst::ICMP_NE) {
4668 Pred = ICmpInst::ICMP_EQ;
4670 }
4671
4672
4673
4674
4675 if (TrueVal->getType()->isIntOrIntVectorTy()) {
4683 X->getType()->getScalarSizeInBits());
4685 return X;
4686 }
4687 }
4688
4689 if (Pred == ICmpInst::ICMP_EQ && match(CmpRHS, m_Zero())) {
4694 true))
4695 return V;
4696
4697
4701
4702
4703 if (match(TrueVal, isFsh) && FalseVal == X && CmpLHS == ShAmt)
4704 return X;
4705
4706
4707
4708
4709
4710
4711 auto isRotate =
4714
4715
4716 if (match(FalseVal, isRotate) && TrueVal == X && CmpLHS == ShAmt &&
4717 Pred == ICmpInst::ICMP_EQ)
4718 return FalseVal;
4719
4720
4721
4722 if (match(TrueVal, m_IntrinsicIntrinsic::abs(m_Specific(CmpLHS))) &&
4724 return FalseVal;
4725 if (match(TrueVal,
4726 m_Neg(m_IntrinsicIntrinsic::abs(m_Specific(CmpLHS)))) &&
4727 match(FalseVal, m_IntrinsicIntrinsic::abs(m_Specific(CmpLHS))))
4728 return FalseVal;
4729 }
4730
4731
4734 return V;
4735
4736
4737
4738
4739 if (Pred == ICmpInst::ICMP_EQ) {
4741 FalseVal, Q, MaxRecurse))
4742 return V;
4744 FalseVal, Q, MaxRecurse))
4745 return V;
4746
4749
4752
4754 {{X, CmpRHS}, {Y, CmpRHS}}, TrueVal, FalseVal, Q, MaxRecurse))
4755 return V;
4756 }
4757
4758
4761
4763 {{X, CmpRHS}, {Y, CmpRHS}}, TrueVal, FalseVal, Q, MaxRecurse))
4764 return V;
4765 }
4766 }
4767
4768 return nullptr;
4769}
4770
4771
4772
4775 unsigned MaxRecurse) {
4777 Value *CmpLHS, *CmpRHS;
4779 return nullptr;
4781
4782 bool IsEquiv = I->isEquivalence();
4783 if (I->isEquivalence(true)) {
4785 Pred = FCmpInst::getInversePredicate(Pred);
4786 IsEquiv = true;
4787 }
4788
4789
4790
4791 if (IsEquiv) {
4793 MaxRecurse))
4794 return V;
4796 MaxRecurse))
4797 return V;
4798 }
4799
4800
4801 if (CmpLHS == F && CmpRHS == T)
4803
4804 if (CmpLHS != T || CmpRHS != F)
4805 return nullptr;
4806
4807
4809
4810 if (Pred == FCmpInst::FCMP_OEQ)
4811 return F;
4812
4813
4814 if (Pred == FCmpInst::FCMP_UNE)
4815 return T;
4816 }
4817
4818 return nullptr;
4819}
4820
4821
4822
4825 if (auto *CondC = dyn_cast(Cond)) {
4826 if (auto *TrueC = dyn_cast(TrueVal))
4827 if (auto *FalseC = dyn_cast(FalseVal))
4829 return C;
4830
4831
4832 if (isa(CondC))
4834
4835
4837 return isa(FalseVal) ? FalseVal : TrueVal;
4838
4839
4840
4841
4842
4844 return TrueVal;
4846 return FalseVal;
4847 }
4848
4849 assert(Cond->getType()->isIntOrIntVectorTy(1) &&
4850 "Select must have bool or bool vector condition");
4851 assert(TrueVal->getType() == FalseVal->getType() &&
4852 "Select must have same types for true/false ops");
4853
4854 if (Cond->getType() == TrueVal->getType()) {
4855
4857 return Cond;
4858
4859
4861 return FalseVal;
4862
4863
4865 return TrueVal;
4866
4867
4871
4872
4874
4877
4880
4881
4883 return TrueVal;
4884
4886 return Cond;
4887
4888
4892 return X;
4895 return X;
4896 }
4897
4898
4900
4903
4906
4907
4909 return FalseVal;
4910
4912 return Cond;
4913 }
4914 }
4915
4916
4917 if (TrueVal == FalseVal)
4918 return TrueVal;
4919
4920 if (Cond == TrueVal) {
4921
4923 return Cond;
4924
4927 }
4928 if (Cond == FalseVal) {
4929
4931 return Cond;
4932
4935 }
4936
4937
4938
4939
4940
4941
4942 if (isa(TrueVal) ||
4944 return FalseVal;
4945
4946
4947 if (isa(FalseVal) ||
4949 return TrueVal;
4950
4951
4953 if (isa(TrueVal->getType()) &&
4956 unsigned NumElts =
4957 cast(TrueC->getType())->getNumElements();
4959 for (unsigned i = 0; i != NumElts; ++i) {
4960
4963 if (!TEltC || !FEltC)
4964 break;
4965
4966
4967
4968 if (TEltC == FEltC)
4970 else if (isa(TEltC) ||
4973 else if (isa(FEltC) ||
4976 else
4977 break;
4978 }
4979 if (NewC.size() == NumElts)
4981 }
4982
4985 return V;
4986
4988 return V;
4989
4991 if (Imp)
4992 return *Imp ? TrueVal : FalseVal;
4993
4994 return nullptr;
4995}
4996
4999 return ::simplifySelectInst(Cond, TrueVal, FalseVal, Q, RecursionLimit);
5000}
5001
5002
5003
5007
5008 unsigned AS =
5009 cast(Ptr->getType()->getScalarType())->getAddressSpace();
5010
5011
5012 if (Indices.empty())
5013 return Ptr;
5014
5015
5017 Type *GEPTy = Ptr->getType();
5019 for (Value *Op : Indices) {
5020
5021
5022 if (VectorType *VT = dyn_cast(Op->getType())) {
5023 GEPTy = VectorType::get(GEPTy, VT->getElementCount());
5024 break;
5025 }
5026 }
5027 }
5028
5029
5030 if (Ptr->getType() == GEPTy &&
5031 all_of(Indices, [](const auto *V) { return match(V, m_Zero()); }))
5032 return Ptr;
5033
5034
5035
5036 if (isa(Ptr) ||
5037 any_of(Indices, [](const auto *V) { return isa(V); }))
5039
5040
5043
5044 bool IsScalableVec =
5046 return isa(V->getType());
5047 });
5048
5049 if (Indices.size() == 1) {
5050 Type *Ty = SrcTy;
5051 if (!IsScalableVec && Ty->isSized()) {
5055
5056 if (TyAllocSize == 0 && Ptr->getType() == GEPTy)
5057 return Ptr;
5058
5059
5060
5061 if (Indices[0]->getType()->getScalarSizeInBits() ==
5063 auto CanSimplify = [GEPTy, &P, Ptr]() -> bool {
5064 return P->getType() == GEPTy &&
5066 };
5067
5068 if (TyAllocSize == 1 &&
5069 match(Indices[0],
5071 CanSimplify())
5072 return P;
5073
5074
5075
5079 TyAllocSize == 1ULL << C && CanSimplify())
5080 return P;
5081
5082
5083
5087 CanSimplify())
5088 return P;
5089 }
5090 }
5091 }
5092
5095 [](Value *Idx) { return match(Idx, m_Zero()); })) {
5096 unsigned IdxWidth =
5099 APInt BasePtrOffset(IdxWidth, 0);
5100 Value *StrippedBasePtr =
5101 Ptr->stripAndAccumulateInBoundsConstantOffsets(Q.DL, BasePtrOffset);
5102
5103
5104
5105
5106
5107
5110 !BasePtrOffset.isZero()) {
5111 auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset);
5113 }
5114
5117 !BasePtrOffset.isOne()) {
5118 auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset - 1);
5120 }
5121 }
5122 }
5123
5124
5125 if (!isa(Ptr) ||
5126 (Indices, [](Value *V) { return isa(V); }))
5127 return nullptr;
5128
5131 Indices);
5132
5133 auto *CE =
5136}
5137
5140 return ::simplifyGEPInst(SrcTy, Ptr, Indices, NW, Q, RecursionLimit);
5141}
5142
5143
5144
5148 if (Constant *CAgg = dyn_cast(Agg))
5149 if (Constant *CVal = dyn_cast(Val))
5151
5152
5153
5154 if (isa(Val) ||
5156 return Agg;
5157
5158
5160 if (EV->getAggregateOperand()->getType() == Agg->getType() &&
5161 EV->getIndices() == Idxs) {
5162
5163
5164 if (isa(Agg) ||
5167 return EV->getAggregateOperand();
5168
5169
5170 if (Agg == EV->getAggregateOperand())
5171 return Agg;
5172 }
5173
5174 return nullptr;
5175}
5176
5180 return ::simplifyInsertValueInst(Agg, Val, Idxs, Q, RecursionLimit);
5181}
5182
5185
5186 auto *VecC = dyn_cast(Vec);
5187 auto *ValC = dyn_cast(Val);
5188 auto *IdxC = dyn_cast(Idx);
5189 if (VecC && ValC && IdxC)
5191
5192
5193 if (auto *CI = dyn_cast(Idx)) {
5194 if (isa(Vec->getType()) &&
5195 CI->uge(cast(Vec->getType())->getNumElements()))
5197 }
5198
5199
5202
5203
5204
5205 if (isa(Val) ||
5207 return Vec;
5208
5209
5210 if (VecC && ValC && VecC->getSplatValue() == ValC)
5211 return Vec;
5212
5213
5214
5215
5217 return Vec;
5218
5219 return nullptr;
5220}
5221
5222
5223
5226 if (auto *CAgg = dyn_cast(Agg))
5228
5229
5230 unsigned NumIdxs = Idxs.size();
5231 for (auto *IVI = dyn_cast(Agg); IVI != nullptr;
5232 IVI = dyn_cast(IVI->getAggregateOperand())) {
5234 unsigned NumInsertValueIdxs = InsertValueIdxs.size();
5235 unsigned NumCommonIdxs = std::min(NumInsertValueIdxs, NumIdxs);
5236 if (InsertValueIdxs.slice(0, NumCommonIdxs) ==
5237 Idxs.slice(0, NumCommonIdxs)) {
5238 if (NumIdxs == NumInsertValueIdxs)
5239 return IVI->getInsertedValueOperand();
5240 break;
5241 }
5242 }
5243
5244 return nullptr;
5245}
5246
5249 return ::simplifyExtractValueInst(Agg, Idxs, Q, RecursionLimit);
5250}
5251
5252
5253
5256 auto *VecVTy = cast(Vec->getType());
5257 if (auto *CVec = dyn_cast(Vec)) {
5258 if (auto *CIdx = dyn_cast(Idx))
5260
5263 }
5264
5265
5266
5269
5270
5271
5272 if (auto *IdxC = dyn_cast(Idx)) {
5273
5274 unsigned MinNumElts = VecVTy->getElementCount().getKnownMinValue();
5275 if (isa(VecVTy) && IdxC->getValue().uge(MinNumElts))
5277
5278 if (IdxC->getValue().ult(MinNumElts))
5282 return Elt;
5283 } else {
5284
5285
5286
5287
5288 auto *IE = dyn_cast(Vec);
5289 if (IE && IE->getOperand(2) == Idx)
5290 return IE->getOperand(1);
5291
5292
5295 }
5296 return nullptr;
5297}
5298
5301 return ::simplifyExtractElementInst(Vec, Idx, Q, RecursionLimit);
5302}
5303
5304
5307
5308
5309
5310
5311
5312
5313 Value *CommonValue = nullptr;
5314 bool HasPoisonInput = false;
5315 bool HasUndefInput = false;
5317
5319 continue;
5320 if (isa(Incoming)) {
5321 HasPoisonInput = true;
5322 continue;
5323 }
5325
5326 HasUndefInput = true;
5327 continue;
5328 }
5329 if (CommonValue && Incoming != CommonValue)
5330 return nullptr;
5332 }
5333
5334
5335
5336 if (!CommonValue)
5339
5340 if (HasPoisonInput || HasUndefInput) {
5341
5342
5343
5345 return nullptr;
5346
5347
5348 if (HasUndefInput &&
5350 return nullptr;
5351 return CommonValue;
5352 }
5353
5354 return CommonValue;
5355}
5356
5359 if (auto *C = dyn_cast(Op))
5361
5362 if (auto *CI = dyn_cast(Op)) {
5363 auto *Src = CI->getOperand(0);
5364 Type *SrcTy = Src->getType();
5365 Type *MidTy = CI->getType();
5366 Type *DstTy = Ty;
5367 if (Src->getType() == Ty) {
5370 Type *SrcIntPtrTy =
5372 Type *MidIntPtrTy =
5374 Type *DstIntPtrTy =
5377 SrcIntPtrTy, MidIntPtrTy,
5378 DstIntPtrTy) == Instruction::BitCast)
5379 return Src;
5380 }
5381 }
5382
5383
5384 if (CastOpc == Instruction::BitCast)
5385 if (Op->getType() == Ty)
5386 return Op;
5387
5388
5390 if (CastOpc == Instruction::PtrToInt &&
5394 return X;
5395
5396 return nullptr;
5397}
5398
5401 return ::simplifyCastInst(CastOpc, Op, Ty, Q, RecursionLimit);
5402}
5403
5404
5405
5406
5408 int MaskVal, Value *RootVec,
5409 unsigned MaxRecurse) {
5410 if (!MaxRecurse--)
5411 return nullptr;
5412
5413
5414
5415 if (MaskVal == -1)
5416 return nullptr;
5417
5418
5419 int InVecNumElts = cast(Op0->getType())->getNumElements();
5420 int RootElt = MaskVal;
5421 Value *SourceOp = Op0;
5422 if (MaskVal >= InVecNumElts) {
5423 RootElt = MaskVal - InVecNumElts;
5424 SourceOp = Op1;
5425 }
5426
5427
5428
5429 if (auto *SourceShuf = dyn_cast(SourceOp)) {
5431 DestElt, SourceShuf->getOperand(0), SourceShuf->getOperand(1),
5432 SourceShuf->getMaskValue(RootElt), RootVec, MaxRecurse);
5433 }
5434
5435
5436
5437 if (!RootVec)
5438 RootVec = SourceOp;
5439
5440
5441 if (RootVec != SourceOp)
5442 return nullptr;
5443
5444
5445
5446 if (RootElt != DestElt)
5447 return nullptr;
5448
5449 return RootVec;
5450}
5451
5455 unsigned MaxRecurse) {
5458
5459 auto *InVecTy = cast(Op0->getType());
5460 unsigned MaskNumElts = Mask.size();
5461 ElementCount InVecEltCount = InVecTy->getElementCount();
5462
5463 bool Scalable = InVecEltCount.isScalable();
5464
5466 Indices.assign(Mask.begin(), Mask.end());
5467
5468
5469
5470 if (!Scalable) {
5471 bool MaskSelects0 = false, MaskSelects1 = false;
5473 for (unsigned i = 0; i != MaskNumElts; ++i) {
5474 if (Indices[i] == -1)
5475 continue;
5476 if ((unsigned)Indices[i] < InVecNumElts)
5477 MaskSelects0 = true;
5478 else
5479 MaskSelects1 = true;
5480 }
5481 if (!MaskSelects0)
5483 if (!MaskSelects1)
5485 }
5486
5487 auto *Op0Const = dyn_cast(Op0);
5488 auto *Op1Const = dyn_cast(Op1);
5489
5490
5491
5492
5493 if (Op0Const && Op1Const)
5495
5496
5497
5498
5499 if (!Scalable && Op0Const && !Op1Const) {
5503 }
5504
5505
5506
5507
5508
5509
5510
5515
5517 if (all_of(Indices, [InsertIndex](int MaskElt) {
5518 return MaskElt == InsertIndex || MaskElt == -1;
5519 })) {
5520 assert(isa(Op1) && "Expected undef operand 1 for splat");
5521
5522
5524 for (unsigned i = 0; i != MaskNumElts; ++i)
5525 if (Indices[i] == -1)
5528 }
5529 }
5530
5531
5532
5533 if (auto *OpShuf = dyn_cast(Op0))
5535 all_equal(OpShuf->getShuffleMask()))
5536 return Op0;
5537
5538
5539
5540 if (Scalable)
5541 return nullptr;
5542
5543
5544
5545
5547 return nullptr;
5548
5549
5550
5551
5552
5553 Value *RootVec = nullptr;
5554 for (unsigned i = 0; i != MaskNumElts; ++i) {
5555
5556
5557 RootVec =
5559
5560
5561 if (!RootVec || RootVec->getType() != RetTy)
5562 return nullptr;
5563 }
5564 return RootVec;
5565}
5566
5567
5571 return ::simplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit);
5572}
5573
5576 if (auto *C = dyn_cast(Op))
5578 return nullptr;
5579}
5580
5581
5582
5586 return C;
5587
5589
5591 return X;
5592
5593 return nullptr;
5594}
5595
5599}
5600
5601
5602
5604 Type *Ty = In->getType();
5605 if (auto *VecTy = dyn_cast(Ty)) {
5606 unsigned NumElts = VecTy->getNumElements();
5608 for (unsigned i = 0; i != NumElts; ++i) {
5609 Constant *EltC = In->getAggregateElement(i);
5610
5611
5612 if (EltC && isa(EltC))
5613 NewC[i] = EltC;
5614 else if (EltC && EltC->isNaN())
5615 NewC[i] = ConstantFP::get(
5616 EltC->getType(), cast(EltC)->getValue().makeQuiet());
5617 else
5619 }
5621 }
5622
5623
5624
5625 if (!In->isNaN())
5627
5628
5629
5630 if (isa(Ty)) {
5631 auto *Splat = In->getSplatValue();
5633 "Found a scalable-vector NaN but not a splat");
5635 }
5636
5637
5638
5639 return ConstantFP::get(Ty, cast(In)->getValue().makeQuiet());
5640}
5641
5642
5643
5644
5649
5650
5653
5654 for (Value *V : Ops) {
5658
5659
5660
5661
5662 if (FMF.noNaNs() && (IsNan || IsUndef))
5664 if (FMF.noInfs() && (IsInf || IsUndef))
5666
5668
5669
5670
5671
5672 if (IsUndef)
5674 if (IsNan)
5677 if (IsNan)
5679 }
5680 }
5681 return nullptr;
5682}
5683
5684
5685
5690 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5693 return C;
5694
5696 return C;
5697
5698
5699
5700
5701
5702
5707 return Op0;
5708
5709
5713 return Op0;
5714
5716 return nullptr;
5717
5719
5721 return Op1;
5722
5723
5724
5725
5726
5727
5728
5729
5733
5737 }
5738
5739
5740
5745 return X;
5746
5747 return nullptr;
5748}
5749
5750
5751
5756 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5759 return C;
5760
5762 return C;
5763
5764
5769 return Op0;
5770
5771
5775 return Op0;
5776
5777
5778
5782 return X;
5783
5784
5785
5790 return X;
5791
5793 return nullptr;
5794
5796
5797 if (Op0 == Op1)
5799
5800
5802 return Op0;
5803
5804
5806 return foldConstant(Instruction::FNeg, Op1, Q);
5807 }
5808
5809
5810
5814 return X;
5815
5816 return nullptr;
5817}
5818
5824 return C;
5825
5827 return nullptr;
5828
5829
5832
5833
5835 return Op0;
5836
5838
5841
5845
5846 if (Known.SignBit == false)
5847 return Op1;
5848
5849 if (Known.SignBit == true)
5850 return foldConstant(Instruction::FNeg, Op1, Q);
5851 }
5852 }
5853
5854
5855
5856
5857
5861 return X;
5862
5863 return nullptr;
5864}
5865
5866
5871 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5874 return C;
5875
5876
5877 return simplifyFMAFMul(Op0, Op1, FMF, Q, MaxRecurse, ExBehavior, Rounding);
5878}
5879
5884 return ::simplifyFAddInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5885 Rounding);
5886}
5887
5892 return ::simplifyFSubInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5893 Rounding);
5894}
5895
5900 return ::simplifyFMulInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5901 Rounding);
5902}
5903
5908 return ::simplifyFMAFMul(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5909 Rounding);
5910}
5911
5916 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5919 return C;
5920
5922 return C;
5923
5925 return nullptr;
5926
5927
5929 return Op0;
5930
5931
5932
5933
5936
5938
5939
5940 if (Op0 == Op1)
5941 return ConstantFP::get(Op0->getType(), 1.0);
5942
5943
5946 return X;
5947
5948
5949
5950
5953 return ConstantFP::get(Op0->getType(), -1.0);
5954
5955
5958 }
5959
5960 return nullptr;
5961}
5962
5967 return ::simplifyFDivInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5968 Rounding);
5969}
5970
5975 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5978 return C;
5979
5981 return C;
5982
5984 return nullptr;
5985
5986
5987
5988
5990
5993
5996 }
5997
5998 return nullptr;
5999}
6000
6005 return ::simplifyFRemInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
6006 Rounding);
6007}
6008
6009
6010
6011
6012
6014 unsigned MaxRecurse) {
6015 switch (Opcode) {
6016 case Instruction::FNeg:
6018 default:
6020 }
6021}
6022
6023
6024
6025
6028 unsigned MaxRecurse) {
6029 switch (Opcode) {
6030 case Instruction::FNeg:
6032 default:
6034 }
6035}
6036
6039}
6040
6043 return ::simplifyFPUnOp(Opcode, Op, FMF, Q, RecursionLimit);
6044}
6045
6046
6047
6050 switch (Opcode) {
6051 case Instruction::Add:
6053 MaxRecurse);
6054 case Instruction::Sub:
6056 MaxRecurse);
6057 case Instruction::Mul:
6059 MaxRecurse);
6060 case Instruction::SDiv:
6062 case Instruction::UDiv:
6064 case Instruction::SRem:
6066 case Instruction::URem:
6068 case Instruction::Shl:
6070 MaxRecurse);
6071 case Instruction::LShr:
6073 case Instruction::AShr:
6075 case Instruction::And:
6077 case Instruction::Or:
6079 case Instruction::Xor:
6081 case Instruction::FAdd:
6083 case Instruction::FSub:
6085 case Instruction::FMul:
6087 case Instruction::FDiv:
6089 case Instruction::FRem:
6091 default:
6093 }
6094}
6095
6096
6097
6098
6101 unsigned MaxRecurse) {
6102 switch (Opcode) {
6103 case Instruction::FAdd:
6105 case Instruction::FSub:
6107 case Instruction::FMul:
6109 case Instruction::FDiv:
6111 default:
6113 }
6114}
6115
6119}
6120
6124}
6125
6126
6132}
6133
6137}
6138
6140 switch (ID) {
6141 default:
6142 return false;
6143
6144
6145 case Intrinsic::fabs:
6146 case Intrinsic:🤣
6147 case Intrinsic::ceil:
6148 case Intrinsic::trunc:
6149 case Intrinsic::rint:
6150 case Intrinsic::nearbyint:
6151 case Intrinsic::round:
6152 case Intrinsic::roundeven:
6153 case Intrinsic::canonicalize:
6154 case Intrinsic::arithmetic_fence:
6155 return true;
6156 }
6157}
6158
6159
6160
6162 switch (ID) {
6163 default:
6164 return false;
6165
6166 case Intrinsic:🤣
6167 case Intrinsic::ceil:
6168 case Intrinsic::trunc:
6169 case Intrinsic::rint:
6170 case Intrinsic::nearbyint:
6171 case Intrinsic::round:
6172 case Intrinsic::roundeven:
6173 return true;
6174 }
6175}
6176
6180 APInt PtrOffset;
6182 return nullptr;
6183
6185
6186 auto *OffsetConstInt = dyn_cast(Offset);
6187 if (!OffsetConstInt || OffsetConstInt->getBitWidth() > 64)
6188 return nullptr;
6189
6191 DL.getIndexTypeSizeInBits(Ptr->getType()));
6192 if (OffsetInt.srem(4) != 0)
6193 return nullptr;
6194
6197 if (!Loaded)
6198 return nullptr;
6199
6200 auto *LoadedCE = dyn_cast(Loaded);
6201 if (!LoadedCE)
6202 return nullptr;
6203
6204 if (LoadedCE->getOpcode() == Instruction::Trunc) {
6205 LoadedCE = dyn_cast(LoadedCE->getOperand(0));
6206 if (!LoadedCE)
6207 return nullptr;
6208 }
6209
6210 if (LoadedCE->getOpcode() != Instruction::Sub)
6211 return nullptr;
6212
6213 auto *LoadedLHS = dyn_cast(LoadedCE->getOperand(0));
6214 if (!LoadedLHS || LoadedLHS->getOpcode() != Instruction::PtrToInt)
6215 return nullptr;
6216 auto *LoadedLHSPtr = LoadedLHS->getOperand(0);
6217
6220 APInt LoadedRHSOffset;
6222 DL) ||
6223 PtrSym != LoadedRHSSym || PtrOffset != LoadedRHSOffset)
6224 return nullptr;
6225
6226 return LoadedLHSPtr;
6227}
6228
6229
6231 bool IsStrict) {
6232
6233
6234 if (isa(Op0) || isa(Op1))
6235 return Op0;
6236
6237
6240
6241 if (!IsStrict) {
6242
6243
6244
6246 return Op0;
6247 }
6248
6251
6252
6253
6254
6255
6256
6257 if (C && (C->isZero() || C->isInfinity()))
6258 return Op0;
6259
6260
6261
6262 if (IsStrict)
6263 return nullptr;
6264
6265
6267 return ConstantFP::get(Op0->getType(), C->makeQuiet());
6268
6269
6270
6271
6272
6274 return Op0;
6275
6276 return nullptr;
6277}
6278
6282
6285 if (auto *II = dyn_cast(Op0))
6286 if (II->getIntrinsicID() == IID)
6287 return II;
6288
6290
6291
6292
6293
6294
6295 auto *II = dyn_cast(Op0);
6298 return Op0;
6299 }
6300
6302 switch (IID) {
6303 case Intrinsic::fabs:
6305 return Op0;
6306 break;
6307 case Intrinsic::bswap:
6308
6310 return X;
6311 break;
6312 case Intrinsic::bitreverse:
6313
6315 return X;
6316 break;
6317 case Intrinsic::ctpop: {
6318
6320 Q.DT))
6321 return ConstantInt::get(Op0->getType(), 1);
6322
6323
6326 Q))
6327 return Op0;
6328 break;
6329 }
6330 case Intrinsic::exp:
6331
6332 if (Call->hasAllowReassoc() &&
6333 match(Op0, m_IntrinsicIntrinsic::log(m_Value(X))))
6334 return X;
6335 break;
6336 case Intrinsic::exp2:
6337
6338 if (Call->hasAllowReassoc() &&
6339 match(Op0, m_IntrinsicIntrinsic::log2(m_Value(X))))
6340 return X;
6341 break;
6342 case Intrinsic::exp10:
6343
6344 if (Call->hasAllowReassoc() &&
6345 match(Op0, m_IntrinsicIntrinsic::log10(m_Value(X))))
6346 return X;
6347 break;
6348 case Intrinsic:🪵
6349
6350 if (Call->hasAllowReassoc() &&
6351 match(Op0, m_IntrinsicIntrinsic::exp(m_Value(X))))
6352 return X;
6353 break;
6354 case Intrinsic::log2:
6355
6356 if (Call->hasAllowReassoc() &&
6357 (match(Op0, m_IntrinsicIntrinsic::exp2(m_Value(X))) ||
6360 return X;
6361 break;
6362 case Intrinsic::log10:
6363
6364
6365 if (Call->hasAllowReassoc() &&
6366 (match(Op0, m_IntrinsicIntrinsic::exp10(m_Value(X))) ||
6369 return X;
6370 break;
6371 case Intrinsic::vector_reverse:
6372
6374 return X;
6375
6377 return Op0;
6378 break;
6379 case Intrinsic::frexp: {
6380
6381 if (match(Op0, m_ExtractValue<0>(m_Value(X)))) {
6382 if (match(X, m_IntrinsicIntrinsic::frexp(m_Value())))
6383 return X;
6384 }
6385
6386 break;
6387 }
6388 default:
6389 break;
6390 }
6391
6392 return nullptr;
6393}
6394
6395
6396
6397
6401 return nullptr;
6402
6403 auto *MM0 = dyn_cast(Op0);
6404 if (!MM0)
6405 return nullptr;
6407
6408 if (Op1 == X || Op1 == Y ||
6410
6411 if (IID0 == IID)
6412 return MM0;
6413
6415 return Op1;
6416 }
6417 return nullptr;
6418}
6419
6420
6421
6422
6425 assert((IID == Intrinsic::maxnum || IID == Intrinsic::minnum ||
6426 IID == Intrinsic::maximum || IID == Intrinsic::minimum) &&
6427 "Unsupported intrinsic");
6428
6429 auto *M0 = dyn_cast(Op0);
6430
6431
6432
6433 if ( || M0->getIntrinsicID() != IID)
6434 return nullptr;
6435 Value *X0 = M0->getOperand(0);
6436 Value *Y0 = M0->getOperand(1);
6437
6438
6439
6440
6441
6442
6443 if (X0 == Op1 || Y0 == Op1)
6444 return M0;
6445
6446 auto *M1 = dyn_cast(Op1);
6447 if ()
6448 return nullptr;
6449 Value *X1 = M1->getOperand(0);
6450 Value *Y1 = M1->getOperand(1);
6452
6453
6454
6455
6456
6457
6458 if ((X0 == X1 && Y0 == Y1) || (X0 == Y1 && Y0 == X1))
6460 return M0;
6461
6462 return nullptr;
6463}
6464
6469 unsigned BitWidth = ReturnType->getScalarSizeInBits();
6470 switch (IID) {
6471 case Intrinsic::abs:
6472
6473
6474
6476 return Op0;
6477 break;
6478
6479 case Intrinsic::cttz: {
6482 return X;
6483 break;
6484 }
6485 case Intrinsic::ctlz: {
6488 return X;
6491 break;
6492 }
6493 case Intrinsic::ptrmask: {
6494 if (isa(Op0) || isa(Op1))
6496
6497
6498
6501
6504 "Invalid mask width");
6505
6506
6508 return Op0;
6509
6510
6511
6512
6514 return Op0;
6515
6519
6520
6521 APInt IrrelevantPtrBits =
6522 PtrKnown.Zero.zextOrTrunc(C->getType()->getScalarSizeInBits());
6524 Instruction::Or, C, ConstantInt::get(C->getType(), IrrelevantPtrBits),
6525 Q.DL);
6526 if (C != nullptr && C->isAllOnesValue())
6527 return Op0;
6528 }
6529 break;
6530 }
6531 case Intrinsic::smax:
6532 case Intrinsic::smin:
6533 case Intrinsic::umax:
6534 case Intrinsic::umin: {
6535
6536 if (Op0 == Op1)
6537 return Op0;
6538
6539
6542
6543
6545 return ConstantInt::get(
6547
6550
6551
6553 return ConstantInt::get(ReturnType, *C);
6554
6555
6556
6557
6560 return Op0;
6561
6562
6563
6564 auto *MinMax0 = dyn_cast(Op0);
6565 if (MinMax0 && MinMax0->getIntrinsicID() == IID) {
6566
6567 Value *M00 = MinMax0->getOperand(0), *M01 = MinMax0->getOperand(1);
6568 const APInt *InnerC;
6571 ICmpInst::getNonStrictPredicate(
6573 return Op0;
6574 }
6575 }
6576
6578 return V;
6580 return V;
6581
6585 return Op0;
6587 return Op1;
6588
6589 break;
6590 }
6591 case Intrinsic::scmp:
6592 case Intrinsic::ucmp: {
6593
6594
6597
6599 IID == Intrinsic::scmp ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
6601 return ConstantInt::get(ReturnType, 1);
6602
6604 IID == Intrinsic::scmp ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
6607
6608 break;
6609 }
6610 case Intrinsic::usub_with_overflow:
6611 case Intrinsic::ssub_with_overflow:
6612
6613
6614
6617 break;
6618 case Intrinsic::uadd_with_overflow:
6619 case Intrinsic::sadd_with_overflow:
6620
6621
6624 cast(ReturnType),
6627 }
6628 break;
6629 case Intrinsic::umul_with_overflow:
6630 case Intrinsic::smul_with_overflow:
6631
6632
6635
6636
6639 break;
6640 case Intrinsic::uadd_sat:
6641
6642
6645 [[fallthrough]];
6646 case Intrinsic::sadd_sat:
6647
6648
6649
6650
6653
6654
6656 return Op0;
6657
6659 return Op1;
6660 break;
6661 case Intrinsic::usub_sat:
6662
6665 [[fallthrough]];
6666 case Intrinsic::ssub_sat:
6667
6670
6672 return Op0;
6673 break;
6674 case Intrinsic::load_relative:
6675 if (auto *C0 = dyn_cast(Op0))
6676 if (auto *C1 = dyn_cast(Op1))
6678 break;
6679 case Intrinsic::powi:
6680 if (auto *Power = dyn_cast(Op1)) {
6681
6682 if (Power->isZero())
6683 return ConstantFP::get(Op0->getType(), 1.0);
6684
6685 if (Power->isOne())
6686 return Op0;
6687 }
6688 break;
6689 case Intrinsic::ldexp:
6691 case Intrinsic::copysign:
6692
6693 if (Op0 == Op1)
6694 return Op0;
6695
6696
6699 return Op1;
6700 break;
6701 case Intrinsic::is_fpclass: {
6702 if (isa(Op0))
6704
6705 uint64_t Mask = cast(Op1)->getZExtValue();
6706
6708 return ConstantInt::get(ReturnType, true);
6710 return ConstantInt::get(ReturnType, false);
6713 break;
6714 }
6715 case Intrinsic::maxnum:
6716 case Intrinsic::minnum:
6717 case Intrinsic::maximum:
6718 case Intrinsic::minimum: {
6719
6720 if (Op0 == Op1)
6721 return Op0;
6722
6723
6724 if (isa(Op0))
6726
6727
6729 return Op0;
6730
6731 bool PropagateNaN = IID == Intrinsic::minimum || IID == Intrinsic::maximum;
6732 bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum;
6733
6734
6735
6736
6737
6739 return PropagateNaN ? propagateNaN(cast(Op1)) : Op0;
6740
6741
6742
6745 (C->isInfinity() || (Call && Call->hasNoInfs() && C->isLargest()))) {
6746
6747
6748
6749
6750 if (C->isNegative() == IsMin &&
6751 (!PropagateNaN || (Call && Call->hasNoNaNs())))
6752 return ConstantFP::get(ReturnType, *C);
6753
6754
6755
6756
6757
6758 if (C->isNegative() != IsMin &&
6759 (PropagateNaN || (Call && Call->hasNoNaNs())))
6760 return Op0;
6761 }
6762
6763
6764
6766 return V;
6768 return V;
6769
6770 break;
6771 }
6772 case Intrinsic::vector_extract: {
6773
6774 unsigned IdxN = cast(Op1)->getZExtValue();
6778 IdxN == 0 && X->getType() == ReturnType)
6779 return X;
6780
6781 break;
6782 }
6783 default:
6784 break;
6785 }
6786
6787 return nullptr;
6788}
6789
6793
6794 assert(Call->arg_size() == Args.size());
6795 unsigned NumOperands = Args.size();
6796 Function *F = cast(Callee);
6798
6799
6800
6801 if (!NumOperands) {
6802 switch (IID) {
6803 case Intrinsic::vscale: {
6807 return ConstantInt::get(RetTy, C->getZExtValue());
6808 return nullptr;
6809 }
6810 default:
6811 return nullptr;
6812 }
6813 }
6814
6815 if (NumOperands == 1)
6817
6818 if (NumOperands == 2)
6820 Call);
6821
6822
6823 switch (IID) {
6824 case Intrinsic::masked_load:
6825 case Intrinsic::masked_gather: {
6826 Value *MaskArg = Args[2];
6827 Value *PassthruArg = Args[3];
6828
6830 return PassthruArg;
6831 return nullptr;
6832 }
6833 case Intrinsic::fshl:
6834 case Intrinsic::fshr: {
6835 Value *Op0 = Args[0], *Op1 = Args[1], *ShAmtArg = Args[2];
6836
6837
6840
6841
6843 return Args[IID == Intrinsic::fshl ? 0 : 1];
6844
6845 const APInt *ShAmtC;
6847
6850 return Args[IID == Intrinsic::fshl ? 0 : 1];
6851 }
6852
6853
6855 return ConstantInt::getNullValue(F->getReturnType());
6856
6857
6859 return ConstantInt::getAllOnesValue(F->getReturnType());
6860
6861 return nullptr;
6862 }
6863 case Intrinsic::experimental_constrained_fma: {
6864 auto *FPI = cast(Call);
6865 if (Value *V = simplifyFPOp(Args, {}, Q, *FPI->getExceptionBehavior(),
6866 *FPI->getRoundingMode()))
6867 return V;
6868 return nullptr;
6869 }
6870 case Intrinsic::fma:
6871 case Intrinsic::fmuladd: {
6873 RoundingMode::NearestTiesToEven))
6874 return V;
6875 return nullptr;
6876 }
6877 case Intrinsic::smul_fix:
6878 case Intrinsic::smul_fix_sat: {
6879 Value *Op0 = Args[0];
6880 Value *Op1 = Args[1];
6881 Value *Op2 = Args[2];
6882 Type *ReturnType = F->getReturnType();
6883
6884
6885
6886
6887 if (isa(Op0))
6889
6890
6893
6894
6897
6898
6899 APInt ScaledOne =
6901 cast(Op2)->getZExtValue());
6903 return Op0;
6904
6905 return nullptr;
6906 }
6907 case Intrinsic::vector_insert: {
6908 Value *Vec = Args[0];
6909 Value *SubVec = Args[1];
6911 Type *ReturnType = F->getReturnType();
6912
6913
6914
6915 unsigned IdxN = cast(Idx)->getZExtValue();
6917 if (match(SubVec,
6918 m_IntrinsicIntrinsic::vector\_extract(m_Value(X), m_Zero())) &&
6919 (Q.isUndefValue(Vec) || Vec == X) && IdxN == 0 &&
6920 X->getType() == ReturnType)
6921 return X;
6922
6923 return nullptr;
6924 }
6925 case Intrinsic::experimental_constrained_fadd: {
6926 auto *FPI = cast(Call);
6927 return simplifyFAddInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6928 *FPI->getExceptionBehavior(),
6929 *FPI->getRoundingMode());
6930 }
6931 case Intrinsic::experimental_constrained_fsub: {
6932 auto *FPI = cast(Call);
6933 return simplifyFSubInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6934 *FPI->getExceptionBehavior(),
6935 *FPI->getRoundingMode());
6936 }
6937 case Intrinsic::experimental_constrained_fmul: {
6938 auto *FPI = cast(Call);
6939 return simplifyFMulInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6940 *FPI->getExceptionBehavior(),
6941 *FPI->getRoundingMode());
6942 }
6943 case Intrinsic::experimental_constrained_fdiv: {
6944 auto *FPI = cast(Call);
6945 return simplifyFDivInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6946 *FPI->getExceptionBehavior(),
6947 *FPI->getRoundingMode());
6948 }
6949 case Intrinsic::experimental_constrained_frem: {
6950 auto *FPI = cast(Call);
6951 return simplifyFRemInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6952 *FPI->getExceptionBehavior(),
6953 *FPI->getRoundingMode());
6954 }
6955 case Intrinsic::experimental_constrained_ldexp:
6956 return simplifyLdexp(Args[0], Args[1], Q, true);
6957 case Intrinsic::experimental_gc_relocate: {
6961
6962
6963 if (isa(DerivedPtr) || isa(BasePtr)) {
6965 }
6966
6967 if (auto *PT = dyn_cast(GCR.getType())) {
6968
6969
6970
6971 if (isa(DerivedPtr)) {
6972
6974 }
6975 }
6976 return nullptr;
6977 }
6978 default:
6979 return nullptr;
6980 }
6981}
6982
6986 auto *F = dyn_cast(Callee);
6988 return nullptr;
6989
6991 ConstantArgs.reserve(Args.size());
6992 for (Value *Arg : Args) {
6993 Constant *C = dyn_cast(Arg);
6994 if () {
6995 if (isa(Arg))
6996 continue;
6997 return nullptr;
6998 }
7000 }
7001
7003}
7004
7007
7008 assert(Call->arg_size() == Args.size());
7009
7010
7011
7012 if (Call->isMustTailCall())
7013 return nullptr;
7014
7015
7016
7017 if (isa(Callee) || isa(Callee))
7019
7021 return V;
7022
7023 auto *F = dyn_cast(Callee);
7024 if (F && F->isIntrinsic())
7026 return Ret;
7027
7028 return nullptr;
7029}
7030
7032 assert(isa(Call));
7035 return V;
7037 return Ret;
7038 return nullptr;
7039}
7040
7041
7043
7045 return Op0;
7046
7047 return nullptr;
7048}
7049
7051 return ::simplifyFreezeInst(Op0, Q);
7052}
7053
7057 return nullptr;
7058
7059 if (auto *PtrOpC = dyn_cast(PtrOp))
7061
7062
7063
7065 if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
7066 return nullptr;
7067
7068
7069
7072 return C;
7073
7074
7075
7079 true);
7080 if (PtrOp == GV) {
7081
7084 Q.DL);
7085 }
7086
7087 return nullptr;
7088}
7089
7090
7091
7092
7096 unsigned MaxRecurse) {
7097 assert(I->getFunction() && "instruction should be inserted in a function");
7099 "context instruction should be in the same function");
7100
7102
7103 switch (I->getOpcode()) {
7104 default:
7105 if (llvm::all_of(NewOps, [](Value *V) { return isa(V); })) {
7108 [](Value *V) { return cast(V); });
7110 }
7111 return nullptr;
7112 case Instruction::FNeg:
7113 return simplifyFNegInst(NewOps[0], I->getFastMathFlags(), Q, MaxRecurse);
7114 case Instruction::FAdd:
7115 return simplifyFAddInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
7116 MaxRecurse);
7117 case Instruction::Add:
7121 case Instruction::FSub:
7122 return simplifyFSubInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
7123 MaxRecurse);
7124 case Instruction::Sub:
7128 case Instruction::FMul:
7129 return simplifyFMulInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
7130 MaxRecurse);
7131 case Instruction::Mul:
7135 case Instruction::SDiv:
7137 Q.IIQ.isExact(cast(I)), Q,
7138 MaxRecurse);
7139 case Instruction::UDiv:
7141 Q.IIQ.isExact(cast(I)), Q,
7142 MaxRecurse);
7143 case Instruction::FDiv:
7144 return simplifyFDivInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
7145 MaxRecurse);
7146 case Instruction::SRem:
7147 return simplifySRemInst(NewOps[0], NewOps[1], Q, MaxRecurse);
7148 case Instruction::URem:
7149 return simplifyURemInst(NewOps[0], NewOps[1], Q, MaxRecurse);
7150 case Instruction::FRem:
7151 return simplifyFRemInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
7152 MaxRecurse);
7153 case Instruction::Shl:
7157 case Instruction::LShr:
7159 Q.IIQ.isExact(cast(I)), Q,
7160 MaxRecurse);
7161 case Instruction::AShr:
7163 Q.IIQ.isExact(cast(I)), Q,
7164 MaxRecurse);
7165 case Instruction::And:
7166 return simplifyAndInst(NewOps[0], NewOps[1], Q, MaxRecurse);
7167 case Instruction::Or:
7168 return simplifyOrInst(NewOps[0], NewOps[1], Q, MaxRecurse);
7169 case Instruction::Xor:
7170 return simplifyXorInst(NewOps[0], NewOps[1], Q, MaxRecurse);
7171 case Instruction::ICmp:
7172 return simplifyICmpInst(cast(I)->getCmpPredicate(), NewOps[0],
7173 NewOps[1], Q, MaxRecurse);
7174 case Instruction::FCmp:
7175 return simplifyFCmpInst(cast(I)->getPredicate(), NewOps[0],
7176 NewOps[1], I->getFastMathFlags(), Q, MaxRecurse);
7177 case Instruction::Select:
7178 return simplifySelectInst(NewOps[0], NewOps[1], NewOps[2], Q, MaxRecurse);
7179 case Instruction::GetElementPtr: {
7180 auto *GEPI = cast(I);
7181 return simplifyGEPInst(GEPI->getSourceElementType(), NewOps[0],
7182 ArrayRef(NewOps).slice(1), GEPI->getNoWrapFlags(), Q,
7183 MaxRecurse);
7184 }
7185 case Instruction::InsertValue: {
7188 MaxRecurse);
7189 }
7190 case Instruction::InsertElement:
7192 case Instruction::ExtractValue: {
7193 auto *EVI = cast(I);
7195 MaxRecurse);
7196 }
7197 case Instruction::ExtractElement:
7199 case Instruction::ShuffleVector: {
7200 auto *SVI = cast(I);
7202 SVI->getShuffleMask(), SVI->getType(), Q,
7203 MaxRecurse);
7204 }
7205 case Instruction::PHI:
7207 case Instruction::Call:
7210 NewOps.drop_back(1 + cast(I)->getNumTotalBundleOperands()), Q);
7211 case Instruction::Freeze:
7213#define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc:
7214#include "llvm/IR/Instruction.def"
7215#undef HANDLE_CAST_INST
7217 MaxRecurse);
7218 case Instruction::Alloca:
7219
7220 return nullptr;
7221 case Instruction::Load:
7223 }
7224}
7225
7229 assert(NewOps.size() == I->getNumOperands() &&
7230 "Number of operands should match the instruction!");
7231 return ::simplifyInstructionWithOperands(I, NewOps, SQ, RecursionLimit);
7232}
7233
7237
7238
7239
7240
7242}
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7261 bool Simplified = false;
7264
7265
7266
7267 if (SimpleV) {
7268 for (User *U : I->users())
7269 if (U != I)
7270 Worklist.insert(cast(U));
7271
7272
7273 I->replaceAllUsesWith(SimpleV);
7274
7275 if (->isEHPad() &&
->isTerminator() &&
->mayHaveSideEffects())
7276 I->eraseFromParent();
7277 } else {
7279 }
7280
7281
7282 for (unsigned Idx = 0; Idx != Worklist.size(); ++Idx) {
7284
7285
7287 if (!SimpleV) {
7288 if (UnsimplifiedUsers)
7289 UnsimplifiedUsers->insert(I);
7290 continue;
7291 }
7292
7293 Simplified = true;
7294
7295
7296
7297
7298 for (User *U : I->users())
7299 Worklist.insert(cast(U));
7300
7301
7302 I->replaceAllUsesWith(SimpleV);
7303
7304 if (->isEHPad() &&
->isTerminator() &&
->mayHaveSideEffects())
7305 I->eraseFromParent();
7306 }
7307 return Simplified;
7308}
7309
7314 assert(I != SimpleV && "replaceAndRecursivelySimplify(X,X) is not valid!");
7315 assert(SimpleV && "Must provide a simplified value.");
7317 UnsimplifiedUsers);
7318}
7319
7320namespace llvm {
7323 auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;
7325 auto *TLI = TLIWP ? &TLIWP->getTLI(F) : nullptr;
7328 return {F.getDataLayout(), TLI, DT, AC};
7329}
7330
7333 return {DL, &AR.TLI, &AR.DT, &AR.AC};
7334}
7335
7336template <class T, class... TArgs>
7339 auto *DT = AM.template getCachedResult(F);
7340 auto *TLI = AM.template getCachedResult(F);
7341 auto *AC = AM.template getCachedResult(F);
7342 return {F.getDataLayout(), TLI, DT, AC};
7343}
7346
7349 return false;
7350
7352}
7353
7354}
7355
7356void InstSimplifyFolder::anchor() {}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static Value * simplifyFreezeInst(Value *Op0, const SimplifyQuery &Q)
Given operands for a Freeze, see if we can fold the result.
static Value * simplifyCmpSelFalseCase(CmpPredicate Pred, Value *LHS, Value *RHS, Value *Cond, const SimplifyQuery &Q, unsigned MaxRecurse)
Simplify comparison with false branch of select.
static Value * simplifyCmpSelCase(CmpPredicate Pred, Value *LHS, Value *RHS, Value *Cond, const SimplifyQuery &Q, unsigned MaxRecurse, Constant *TrueOrFalse)
Simplify comparison with true or false branch of select: sel = select i1 cond, i32 tv,...
static Value * simplifySelectWithFakeICmpEq(Value *CmpLHS, Value *CmpRHS, CmpPredicate Pred, Value *TrueVal, Value *FalseVal)
An alternative way to test if a bit is set or not uses sgt/slt instead of eq/ne.
static Value * simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an LShr, see if we can fold the result.
static Value * simplifyUDivInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for a UDiv, see if we can fold the result.
static Value * simplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef< int > Mask, Type *RetTy, const SimplifyQuery &Q, unsigned MaxRecurse)
static Value * foldMinMaxSharedOp(Intrinsic::ID IID, Value *Op0, Value *Op1)
Given a min/max intrinsic, see if it can be removed based on having an operand that is another min/ma...
static Value * simplifySubInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for a Sub, see if we can fold the result.
static Value * simplifyFCmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an FCmpInst, see if we can fold the result.
static Value * expandCommutativeBinOp(Instruction::BinaryOps Opcode, Value *L, Value *R, Instruction::BinaryOps OpcodeToExpand, const SimplifyQuery &Q, unsigned MaxRecurse)
Try to simplify binops of form "A op (B op' C)" or the commuted variant by distributing op over op'.
static Constant * foldOrCommuteConstant(Instruction::BinaryOps Opcode, Value *&Op0, Value *&Op1, const SimplifyQuery &Q)
static bool haveNonOverlappingStorage(const Value *V1, const Value *V2)
Return true if V1 and V2 are each the base of some distict storage region [V, object_size(V)] which d...
static Constant * foldConstant(Instruction::UnaryOps Opcode, Value *&Op, const SimplifyQuery &Q)
static Value * handleOtherCmpSelSimplifications(Value *TCmp, Value *FCmp, Value *Cond, const SimplifyQuery &Q, unsigned MaxRecurse)
We know comparison with both branches of select can be simplified, but they are not equal.
static Value * threadCmpOverPHI(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
In the case of a comparison with a PHI instruction, try to simplify the comparison by seeing whether ...
static Constant * propagateNaN(Constant *In)
Try to propagate existing NaN values when possible.
static Value * simplifyICmpOfBools(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Fold an icmp when its operands have i1 scalar type.
static Value * simplifyICmpWithBinOpOnLHS(CmpPredicate Pred, BinaryOperator *LBO, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
static Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an AShr, see if we can fold the result.
static Value * simplifyRelativeLoad(Constant *Ptr, Constant *Offset, const DataLayout &DL)
static Value * simplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)
These are simplifications common to SDiv and UDiv.
static Value * simplifyPHINode(PHINode *PN, ArrayRef< Value * > IncomingValues, const SimplifyQuery &Q)
See if we can fold the given phi. If not, returns null.
static Value * simplifyExtractValueInst(Value *Agg, ArrayRef< unsigned > Idxs, const SimplifyQuery &, unsigned)
Given operands for an ExtractValueInst, see if we can fold the result.
static Value * simplifySelectInst(Value *, Value *, Value *, const SimplifyQuery &, unsigned)
Given operands for a SelectInst, see if we can fold the result.
static Value * simplifyAddInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an Add, see if we can fold the result.
static Value * simplifyUnOp(unsigned, Value *, const SimplifyQuery &, unsigned)
Given the operand for a UnaryOperator, see if we can fold the result.
static bool isSameCompare(Value *V, CmpPredicate Pred, Value *LHS, Value *RHS)
isSameCompare - Is V equivalent to the comparison "LHS Pred RHS"?
static Value * simplifyAndCommutative(Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)
static Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &SQ, unsigned MaxRecurse)
See if we can compute a simplified version of this instruction.
static bool isIdempotent(Intrinsic::ID ID)
static std::optional< ConstantRange > getRange(Value *V, const InstrInfoQuery &IIQ)
Helper method to get range from metadata or attribute.
static Value * simplifyAndOrOfICmpsWithCtpop(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd)
Try to simplify and/or of icmp with ctpop intrinsic.
static Value * simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp, ICmpInst *UnsignedICmp, bool IsAnd, const SimplifyQuery &Q)
Commuted variants are assumed to be handled by calling this function again with the parameters swappe...
static Value * tryConstantFoldCall(CallBase *Call, Value *Callee, ArrayRef< Value * > Args, const SimplifyQuery &Q)
static Value * simplifyWithOpsReplaced(Value *V, ArrayRef< std::pair< Value *, Value * > > Ops, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags, unsigned MaxRecurse)
static Value * simplifyICmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an ICmpInst, see if we can fold the result.
static Value * simplifyExtractElementInst(Value *Vec, Value *Idx, const SimplifyQuery &Q, unsigned)
Given operands for an ExtractElementInst, see if we can fold the result.
static Value * simplifyAndOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1, const InstrInfoQuery &IIQ)
static Value * simplifyICmpWithMinMax(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
simplify integer comparisons where at least one operand of the compare matches an integer min/max idi...
static Value * simplifyCmpSelTrueCase(CmpPredicate Pred, Value *LHS, Value *RHS, Value *Cond, const SimplifyQuery &Q, unsigned MaxRecurse)
Simplify comparison with true branch of select.
static Value * simplifyIntrinsic(CallBase *Call, Value *Callee, ArrayRef< Value * > Args, const SimplifyQuery &Q)
static void getUnsignedMonotonicValues(SmallPtrSetImpl< Value * > &Res, Value *V, MonotonicType Type, unsigned Depth=0)
Get values V_i such that V uge V_i (GreaterEq) or V ule V_i (LowerEq).
static bool isPoisonShift(Value *Amount, const SimplifyQuery &Q)
Returns true if a shift by Amount always yields poison.
static APInt stripAndComputeConstantOffsets(const DataLayout &DL, Value *&V, bool AllowNonInbounds=false)
Compute the base pointer and cumulative constant offsets for V.
static Value * simplifyCmpInst(CmpPredicate, Value *, Value *, const SimplifyQuery &, unsigned)
Given operands for a CmpInst, see if we can fold the result.
static Value * simplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse, fp::ExceptionBehavior ExBehavior, RoundingMode Rounding)
static Value * simplifyRightShift(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an LShr or AShr, see if we can fold the result.
static Value * simplifyICmpWithIntrinsicOnLHS(CmpPredicate Pred, Value *LHS, Value *RHS)
static Value * simplifySDivInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an SDiv, see if we can fold the result.
static Value * simplifyByDomEq(unsigned Opcode, Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)
Test if there is a dominating equivalence condition for the two operands.
static Value * simplifyFPUnOp(unsigned, Value *, const FastMathFlags &, const SimplifyQuery &, unsigned)
Given the operand for a UnaryOperator, see if we can fold the result.
static Value * simplifyICmpWithBinOp(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
TODO: A large part of this logic is duplicated in InstCombine's foldICmpBinOp().
static Value * simplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for an FAdd, see if we can fold the result.
static Value * simplifyOrOfICmps(ICmpInst *Op0, ICmpInst *Op1, const SimplifyQuery &Q)
static Value * expandBinOp(Instruction::BinaryOps Opcode, Value *V, Value *OtherOp, Instruction::BinaryOps OpcodeToExpand, const SimplifyQuery &Q, unsigned MaxRecurse)
Try to simplify a binary operator of form "V op OtherOp" where V is "(B0 opex B1)" by distributing 'o...
static Value * simplifyICmpWithZero(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Try hard to fold icmp with zero RHS because this is a common case.
static Value * simplifyICmpWithConstant(CmpPredicate Pred, Value *LHS, Value *RHS, const InstrInfoQuery &IIQ)
static Value * simplifySelectWithFCmp(Value *Cond, Value *T, Value *F, const SimplifyQuery &Q, unsigned MaxRecurse)
Try to simplify a select instruction when its condition operand is a floating-point comparison.
static Constant * getFalse(Type *Ty)
For a boolean type or a vector of boolean type, return false or a vector with every element false.
static Value * simplifyDivRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)
Check for common or similar folds of integer division or integer remainder.
static bool removesFPFraction(Intrinsic::ID ID)
Return true if the intrinsic rounds a floating-point value to an integral floating-point value (not a...
static Value * simplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
static Value * simplifyOrOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1, const InstrInfoQuery &IIQ)
static Value * simplifySelectWithEquivalence(ArrayRef< std::pair< Value *, Value * > > Replacements, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q, unsigned MaxRecurse)
Try to simplify a select instruction when its condition operand is an integer equality or floating-po...
static Value * simplifyMulInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for a Mul, see if we can fold the result.
static Value * simplifyFNegInst(Value *Op, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse)
Given the operand for an FNeg, see if we can fold the result.
static Value * simplifyOrInst(Value *, Value *, const SimplifyQuery &, unsigned)
Given operands for an Or, see if we can fold the result.
static bool trySimplifyICmpWithAdds(CmpPredicate Pred, Value *LHS, Value *RHS, const InstrInfoQuery &IIQ)
static Value * simplifySelectBitTest(Value *TrueVal, Value *FalseVal, Value *X, const APInt *Y, bool TrueWhenUnset)
Try to simplify a select instruction when its condition operand is an integer comparison where one op...
static Value * simplifyAssociativeBinOp(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
Generic simplifications for associative binary operations.
static Value * simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an Shl, see if we can fold the result.
static Value * threadBinOpOverPHI(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
In the case of a binary operation with an operand that is a PHI instruction, try to simplify the bino...
static Value * simplifyCmpSelOfMaxMin(Value *CmpLHS, Value *CmpRHS, CmpPredicate Pred, Value *TVal, Value *FVal)
static Value * simplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
static Value * simplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for an FSub, see if we can fold the result.
static Value * simplifyXorInst(Value *, Value *, const SimplifyQuery &, unsigned)
Given operands for a Xor, see if we can fold the result.
static Value * simplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for a URem, see if we can fold the result.
static Constant * simplifyFPOp(ArrayRef< Value * > Ops, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior, RoundingMode Rounding)
Perform folds that are common to any floating-point operation.
static Value * threadCmpOverSelect(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
In the case of a comparison with a select instruction, try to simplify the comparison by seeing wheth...
static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI, const DominatorTree *DT, AssumptionCache *AC, SmallSetVector< Instruction *, 8 > *UnsimplifiedUsers=nullptr)
Implementation of recursive simplification through an instruction's uses.
static bool isAllocDisjoint(const Value *V)
Return true if the underlying object (storage) must be disjoint from storage returned by any noalias ...
static Constant * getTrue(Type *Ty)
For a boolean type or a vector of boolean type, return true or a vector with every element true.
static Value * simplifyGEPInst(Type *, Value *, ArrayRef< Value * >, GEPNoWrapFlags, const SimplifyQuery &, unsigned)
Given operands for an GetElementPtrInst, see if we can fold the result.
static bool isDivZero(Value *X, Value *Y, const SimplifyQuery &Q, unsigned MaxRecurse, bool IsSigned)
Return true if we can simplify X / Y to 0.
static Value * simplifyLdexp(Value *Op0, Value *Op1, const SimplifyQuery &Q, bool IsStrict)
static Value * simplifyLogicOfAddSub(Value *Op0, Value *Op1, Instruction::BinaryOps Opcode)
Given a bitwise logic op, check if the operands are add/sub with a common source value and inverted c...
static Value * simplifyOrLogic(Value *X, Value *Y)
static Type * getCompareTy(Value *Op)
static Value * simplifyCastInst(unsigned, Value *, Type *, const SimplifyQuery &, unsigned)
static Value * simplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1, const SimplifyQuery &Q)
static Value * simplifyBinOp(unsigned, Value *, Value *, const SimplifyQuery &, unsigned)
Given operands for a BinaryOperator, see if we can fold the result.
static bool isICmpTrue(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
Given a predicate and two operands, return true if the comparison is true.
static Value * simplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q, unsigned)
Given operands for an InsertValueInst, see if we can fold the result.
static Value * simplifyAndInst(Value *, Value *, const SimplifyQuery &, unsigned)
Given operands for an And, see if we can fold the result.
static Value * foldIdentityShuffles(int DestElt, Value *Op0, Value *Op1, int MaskVal, Value *RootVec, unsigned MaxRecurse)
For the given destination element of a shuffle, peek through shuffles to match a root vector source o...
static Value * simplifyAndOrOfFCmps(const SimplifyQuery &Q, FCmpInst *LHS, FCmpInst *RHS, bool IsAnd)
static Value * extractEquivalentCondition(Value *V, CmpPredicate Pred, Value *LHS, Value *RHS)
Rummage around inside V looking for something equivalent to the comparison "LHS Pred RHS".
static Value * simplifyAndOrOfCmps(const SimplifyQuery &Q, Value *Op0, Value *Op1, bool IsAnd)
static Value * simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags, unsigned MaxRecurse)
static Value * threadBinOpOverSelect(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)
In the case of a binary operation with a select instruction as an operand, try to simplify the binop ...
static Value * simplifyICmpUsingMonotonicValues(CmpPredicate Pred, Value *LHS, Value *RHS)
static Constant * computePointerDifference(const DataLayout &DL, Value *LHS, Value *RHS)
Compute the constant difference between two pointer values.
static Value * simplifySRemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an SRem, see if we can fold the result.
static Value * simplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given the operands for an FMul, see if we can fold the result.
static Value * simplifyAndOrOfICmpsWithConstants(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd)
Test if a pair of compares with a shared operand and 2 constants has an empty set intersection,...
static Value * simplifyAndOrWithICmpEq(unsigned Opcode, Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)
static Value * simplifyICmpWithDominatingAssume(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
static Value * simplifyShift(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, bool IsNSW, const SimplifyQuery &Q, unsigned MaxRecurse)
Given operands for an Shl, LShr or AShr, see if we can fold the result.
static Constant * computePointerICmp(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
static Value * simplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)
These are simplifications common to SRem and URem.
static bool valueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT)
Does the given value dominate the specified phi node?
static Value * simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q, unsigned MaxRecurse)
Try to simplify a select instruction when its condition operand is an integer comparison.
static Value * foldMinimumMaximumSharedOp(Intrinsic::ID IID, Value *Op0, Value *Op1)
Given a min/max intrinsic, see if it can be removed based on having an operand that is another min/ma...
static Value * simplifyUnaryIntrinsic(Function *F, Value *Op0, const SimplifyQuery &Q, const CallBase *Call)
This header provides classes for managing per-loop analyses.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static SymbolRef::Type getType(const Symbol *Sym)
static const uint32_t IV[8]
Class for arbitrary precision integers.
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
unsigned getActiveBits() const
Compute the number of active bits in the value.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
void setSignBit()
Set the sign bit to 1.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
unsigned countr_zero() const
Count the number of trailing zero bits.
bool isNonPositive() const
Determine if this APInt Value is non-positive (<= 0).
APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
bool isStrictlyPositive() const
Determine if this APInt Value is positive.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
bool getBoolValue() const
Convert APInt to a boolean value.
APInt srem(const APInt &RHS) const
Function for signed remainder operation.
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 ule(const APInt &RHS) const
Unsigned less or equal comparison.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
bool isSignBitSet() const
Determine if sign bit of this APInt is set.
bool slt(const APInt &RHS) const
Signed less than comparison.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
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.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
an instruction to allocate memory on the stack
A container for analyses that lazily runs them and caches their results.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
back - Get the last element.
size_t size() const
size - Get the array size.
ArrayRef< T > drop_back(size_t N=1) const
Drop the last N elements of the array.
bool empty() const
empty - Check if the array is empty.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
An immutable pass that tracks lazily created AssumptionCache objects.
AssumptionCache & getAssumptionCache(Function &F)
Get the cached assumptions for a function.
A cache of @llvm.assume calls within a function.
MutableArrayRef< ResultElem > assumptionsFor(const Value *V)
Access the list of assumptions which affect this value.
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
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
This class represents a function call, abstracting a target machine's calling convention.
static unsigned isEliminableCastPair(Instruction::CastOps firstOpcode, Instruction::CastOps secondOpcode, Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy, Type *DstIntPtrTy)
Determine how a pair of casts can be eliminated, if they can be at all.
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
bool isFalseWhenEqual() const
This is just a convenience.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
bool isTrueWhenEqual() const
This is just a convenience.
bool isFPPredicate() const
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 bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
bool isIntPredicate() const
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static Constant * getBinOpAbsorber(unsigned Opcode, Type *Ty, bool AllowLHSConstant=false)
Return the absorbing element for the given binary operation, i.e.
static Constant * getNot(Constant *C)
static Constant * getInsertElement(Constant *Vec, Constant *Elt, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static Constant * getShuffleVector(Constant *V1, Constant *V2, ArrayRef< int > Mask, Type *OnlyIfReducedTy=nullptr)
static bool isSupportedGetElementPtr(const Type *SrcElemTy)
Whether creating a constant expression for this getelementptr type is supported.
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static Constant * getZero(Type *Ty, bool Negative=false)
static Constant * getNegativeZero(Type *Ty)
static Constant * getNaN(Type *Ty, bool Negative=false, uint64_t Payload=0)
This is the shared class of boolean and integer constants.
static ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static ConstantInt * getFalse(LLVMContext &Context)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static ConstantInt * getBool(LLVMContext &Context, bool V)
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
This class represents a range of values.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
bool isEmptySet() const
Return true if this set contains no members.
static 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...
ConstantRange inverse() const
Return a new range that is the logical not of the current set.
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static Constant * get(StructType *T, ArrayRef< Constant * > V)
static Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static Constant * getAllOnesValue(Type *Ty)
bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool isNaN() const
Return true if this is a floating-point NaN constant or a vector floating-point constant with all NaN...
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
unsigned getIndexTypeSizeInBits(Type *Ty) const
Layout size of the index used in GEP calculation.
IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
unsigned getIndexSizeInBits(unsigned AS) const
Size in bits of index used for address calculation in getelementptr.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
Convenience struct for specifying and reasoning about fast-math flags.
bool noSignedZeros() const
bool allowReassoc() const
Flag queries.
Represents calls to the gc.relocate intrinsic.
Value * getBasePtr() const
Value * getDerivedPtr() const
Represents flags for the getelementptr instruction/expression.
static Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
This instruction compares its operands according to the predicate given to the constructor.
static bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isEquality() const
Return true if this predicate is either EQ or NE.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Predicate getUnsignedPredicate() const
For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
This instruction inserts a struct field of array element value into an aggregate value.
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
bool isAssociative() const LLVM_READONLY
Return true if the instruction is associative:
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
const Function * getFunction() const
Return the function this instruction belongs to.
An instruction for reading from memory.
bool isVolatile() const
Return true if this is a load from a volatile memory location.
static APInt getSaturationPoint(Intrinsic::ID ID, unsigned numBits)
Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values, so there is a certain thre...
ICmpInst::Predicate getPredicate() const
Returns the comparison predicate underlying the intrinsic.
op_range incoming_values()
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
Pass interface - Implemented by all 'passes'.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This class represents a cast from a pointer to an integer.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
static void commuteShuffleMask(MutableArrayRef< int > Mask, unsigned InVecNumElts)
Change values in a shuffle permute mask assuming the two vector operands of length InVecNumElts have ...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetLibraryInfo & getTLI(const Function &F)
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.
bool isPointerTy() const
True if this is an instance of PointerType.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
static IntegerType * getInt32Ty(LLVMContext &C)
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const
Accumulate the constant offset this value has compared to a base pointer.
LLVMContext & getContext() const
All values hold a context through their type.
This class represents zero extension of integer types.
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
class_match< PoisonValue > m_Poison()
Match an arbitrary poison constant.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
PtrAdd_match< PointerOpTy, OffsetOpTy > m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
Matches GEP with i8 source element type.
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
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.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
cstfp_pred_ty< is_inf > m_Inf()
Match a positive or negative infinity FP constant.
m_Intrinsic_Ty< Opnd0 >::Ty m_BitReverse(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
BinaryOp_match< cstfp_pred_ty< is_any_zero_fp >, RHS, Instruction::FSub > m_FNegNSZ(const RHS &X)
Match 'fneg X' as 'fsub +-0.0, X'.
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)
Matches integer division operations.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
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.
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.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
cstfp_pred_ty< is_neg_zero_fp > m_NegZeroFP()
Match a floating-point negative zero.
specific_fpval m_SpecificFP(double V)
Match a specific floating point value or vector with all elements equal to the value.
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)
m_Intrinsic_Ty< Opnd0 >::Ty m_Sqrt(const Opnd0 &Op0)
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::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
cst_pred_ty< custom_checkfn< APInt > > m_CheckedInt(function_ref< bool(const APInt &)> CheckFn)
Match an integer or vector where CheckFn(ele) for each element is true.
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
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.
apfloat_match m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty, true > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty, true > > > m_c_MaxOrMin(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWSub(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CastInst_match< OpTy, SIToFPInst > m_SIToFP(const OpTy &Op)
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)
Exact_match< T > m_Exact(const T &SubPattern)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
BinaryOp_match< LHS, RHS, Instruction::FAdd, true > m_c_FAdd(const LHS &L, const RHS &R)
Matches FAdd with LHS and RHS in either order.
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)
apfloat_match m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
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)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
cstfp_pred_ty< is_nan > m_NaN()
Match an arbitrary NaN constant.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_BSwap(const Opnd0 &Op0)
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.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap > m_NSWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
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.
ExceptionBehavior
Exception behavior used for floating point operations.
@ ebStrict
This corresponds to "fpexcept.strict".
@ ebIgnore
This corresponds to "fpexcept.ignore".
This is an optimization pass for GlobalISel generic memory operations.
Intrinsic::ID getInverseMinMaxIntrinsic(Intrinsic::ID MinMaxID)
Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a AShr, fold the result or return nulll.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Value * simplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for an FMul, fold the result or return null.
Value * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, GEPNoWrapFlags NW, const SimplifyQuery &Q)
Given operands for a GetElementPtrInst, fold the result or return null.
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr, bool AllowEphemerals=false)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
bool canCreatePoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)
Constant * ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2)
Attempt to constant fold a select instruction with the specified operands.
Value * simplifyFreezeInst(Value *Op, const SimplifyQuery &Q)
Given an operand for a Freeze, see if we can fold the result.
Constant * ConstantFoldFPInstOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL, const Instruction *I, bool AllowNonDeterministic=true)
Attempt to constant fold a floating point binary operation with the specified operands,...
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.
bool canConstantFoldCallTo(const CallBase *Call, const Function *F)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
APInt getMinMaxLimit(SelectPatternFlavor SPF, unsigned BitWidth)
Return the minimum or maximum constant value for the specified integer min/max flavor and type.
Value * simplifySDivInst(Value *LHS, Value *RHS, bool IsExact, const SimplifyQuery &Q)
Given operands for an SDiv, fold the result or return null.
Value * simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q)
Given operand for a UnaryOperator, fold the result or return null.
bool isDefaultFPEnvironment(fp::ExceptionBehavior EB, RoundingMode RM)
Returns true if the exception handling behavior and rounding mode match what is used in the default f...
Value * simplifyMulInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Mul, fold the result or return null.
bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, APInt &Offset, const DataLayout &DL, DSOLocalEquivalent **DSOEquiv=nullptr)
If this constant is a constant offset from a global, return the global and the constant.
Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
Value * simplifyCall(CallBase *Call, Value *Callee, ArrayRef< Value * > Args, const SimplifyQuery &Q)
Given a callsite, callee, and arguments, fold the result or return null.
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.
bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to have exactly one bit set when defined.
bool canRoundingModeBe(RoundingMode RM, RoundingMode QRM)
Returns true if the rounding mode RM may be QRM at compile time or at run time.
bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
Value * simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FCmpInst, fold the result or return null.
Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
Constant * ConstantFoldGetElementPtr(Type *Ty, Constant *C, std::optional< ConstantRange > InRange, ArrayRef< Value * > Idxs)
CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)
Return the canonical comparison predicate for the specified minimum/maximum flavor.
Value * simplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef< int > Mask, Type *RetTy, const SimplifyQuery &Q)
Given operands for a ShuffleVectorInst, fold the result or return null.
Constant * ConstantFoldCall(const CallBase *Call, Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
Value * simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Or, fold the result or return null.
Value * simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Xor, fold the result or return null.
ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
ConstantRange computeConstantRange(const Value *V, bool ForSigned, bool UseInstrInfo=true, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
Constant * ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef< unsigned > Idxs)
Attempt to constant fold an extractvalue instruction with the specified operands and indices.
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates memory (either malloc,...
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if 'V & Mask' is known to be zero.
Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
unsigned M1(unsigned Val)
Value * simplifySubInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Sub, fold the result or return null.
Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
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...
Constant * ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty, const DataLayout &DL)
If C is a uniform value where all bits are the same (either all zero, all ones, all undef or all pois...
SelectPatternFlavor getInverseMinMaxFlavor(SelectPatternFlavor SPF)
Return the inverse minimum/maximum flavor of the specified flavor.
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, SmallSetVector< Instruction *, 8 > *UnsimplifiedUsers=nullptr)
Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
SelectPatternFlavor
Specific patterns of select instructions we can match.
Value * simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Shl, fold the result or return null.
Value * simplifyFNegInst(Value *Op, FastMathFlags FMF, const SimplifyQuery &Q)
Given operand for an FNeg, fold the result or return null.
Value * simplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for an FSub, fold the result or return null.
bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
Value * simplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for an FRem, fold the result or return null.
Value * simplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for an FAdd, fold the result or return null.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
Value * simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a LShr, fold the result or return null.
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
ConstantRange getVScaleRange(const Function *F, unsigned BitWidth)
Determine the possible constant range of vscale with the given bit width, based on the vscale_range f...
Constant * ConstantFoldInstOperands(Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
Value * simplifyExtractValueInst(Value *Agg, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)
Given operands for an ExtractValueInst, fold the result or return null.
bool isNotCrossLaneOperation(const Instruction *I)
Return true if the instruction doesn't potentially cross vector lanes.
Value * simplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)
Given operands for an InsertValueInst, fold the result or return null.
Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
Value * simplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for an FDiv, fold the result or return null.
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
Value * simplifyLoadInst(LoadInst *LI, Value *PtrOp, const SimplifyQuery &Q)
Given a load instruction and its pointer operand, fold the result or return null.
Value * simplifyFMAFMul(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for the multiplication of a FMA, fold the result or return null.
Value * simplifyConstrainedFPCall(CallBase *Call, const SimplifyQuery &Q)
Given a constrained FP intrinsic call, tries to compute its simplified version.
Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
bool isKnownNonEqual(const Value *V1, const Value *V2, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given values are known to be non-equal when defined.
@ Or
Bitwise or logical OR of integers.
std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
Value * findScalarElement(Value *V, unsigned EltNo)
Given a vector and an element number, see if the scalar value is already around as a register,...
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
Value * simplifyUDivInst(Value *LHS, Value *RHS, bool IsExact, const SimplifyQuery &Q)
Given operands for a UDiv, fold the result or return null.
DWARFExpression::Operation Op
Value * simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType, Value *Op0, Value *Op1, const SimplifyQuery &Q, const CallBase *Call)
Given operands for a BinaryIntrinsic, fold the result or return null.
RoundingMode
Rounding mode.
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
unsigned M0(unsigned Val)
Value * simplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx, const SimplifyQuery &Q)
Given operands for an InsertElement, fold the result or return null.
constexpr unsigned BitWidth
SelectPatternResult matchDecomposedSelectPattern(CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, 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...
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.
bool maskIsAllZeroOrUndef(Value *Mask)
Given a mask vector of i1, Return true if all of the elements of this predicate mask are known to be ...
std::pair< Value *, FPClassTest > fcmpToClassTest(CmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
Value * simplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an SRem, fold the result or return null.
void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=6)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
std::optional< bool > computeKnownFPSignBit(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return false if we can prove that the specified FP value's sign bit is 0.
unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return the number of times the sign bit of the register is replicated into the other bits.
bool cannotBeNegativeZero(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if we can prove that the specified FP value is never equal to -0.0.
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
Constant * ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, ArrayRef< unsigned > Idxs)
ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue instruction with the spe...
Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
std::optional< bool > isImpliedByDomCondition(const Value *Cond, const Instruction *ContextI, const DataLayout &DL)
Return the boolean condition value in the context of the given instruction if it is known based on do...
Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
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.
KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, unsigned Depth, const SimplifyQuery &SQ)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool isKnownNegation(const Value *X, const Value *Y, bool NeedNSW=false, bool AllowPoison=true)
Return true if the two given values are negation.
Constant * ConstantFoldIntegerCast(Constant *C, Type *DestTy, bool IsSigned, const DataLayout &DL)
Constant fold a zext, sext or trunc, depending on IsSigned and whether the DestTy is wider or narrowe...
const SimplifyQuery getBestSimplifyQuery(Pass &, Function &)
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,...
bool canIgnoreSNaN(fp::ExceptionBehavior EB, FastMathFlags FMF)
Returns true if the possibility of a signaling NaN can be safely ignored.
Value * simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a URem, fold the result or return null.
Value * simplifyExtractElementInst(Value *Vec, Value *Idx, const SimplifyQuery &Q)
Given operands for an ExtractElementInst, fold the result or return null.
Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This callback is used in conjunction with PointerMayBeCaptured.
virtual void tooManyUses()=0
tooManyUses - The depth of traversal has breached a limit.
virtual bool captured(const Use *U)=0
captured - Information about the pointer was captured by the user of use U.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
InstrInfoQuery provides an interface to query additional information for instructions like metadata o...
bool isExact(const BinaryOperator *Op) const
MDNode * getMetadata(const Instruction *I, unsigned KindID) const
bool hasNoSignedWrap(const InstT *Op) const
bool hasNoUnsignedWrap(const InstT *Op) const
bool isNonNegative() const
Returns true if this value is known to be non-negative.
bool isZero() const
Returns true if value is all zero.
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
unsigned countMaxTrailingZeros() const
Returns the maximum number of trailing zero bits possible.
bool hasConflict() const
Returns true if there is conflicting information.
unsigned getBitWidth() const
Get the bit width of this value.
unsigned countMaxActiveBits() const
Returns the maximum number of bits needed to represent all possible unsigned values with these known ...
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
APInt getMinValue() const
Return the minimal unsigned value possible given these KnownBits.
bool isNegative() const
Returns true if this value is known to be negative.
static KnownBits shl(const KnownBits &LHS, const KnownBits &RHS, bool NUW=false, bool NSW=false, bool ShAmtNonZero=false)
Compute known bits for shl(LHS, RHS).
bool isKnownAlwaysNaN() const
Return true if it's known this must always be a nan.
static constexpr FPClassTest OrderedLessThanZeroMask
std::optional< bool > SignBit
std::nullopt if the sign bit is unknown, true if the sign bit is definitely set or false if the sign ...
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
bool isKnownNever(FPClassTest Mask) const
Return true if it's known this can never be one of the mask entries.
bool cannotBeOrderedLessThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
Various options to control the behavior of getObjectSize.
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.
Mode EvalMode
How we want to evaluate this object's size.
SelectPatternFlavor Flavor
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
bool CanUseUndef
Controls whether simplifications are allowed to constrain the range of possible values for uses of un...
SimplifyQuery getWithInstruction(const Instruction *I) const
bool isUndefValue(Value *V) const
If CanUseUndef is true, returns whether V is undef.
const TargetLibraryInfo * TLI
SimplifyQuery getWithoutUndef() const