LLVM: lib/Transforms/InstCombine/InstCombineCasts.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
29#include
30#include
31
32using namespace llvm;
34
35#define DEBUG_TYPE "instcombine"
36
38
42
43
44
46 return Result;
47
50
51
54 unsigned Opc = I->getOpcode();
55 switch (Opc) {
56 case Instruction::Add:
57 case Instruction::Sub:
58 case Instruction::Mul:
59 case Instruction::And:
60 case Instruction::Or:
61 case Instruction::Xor:
62 case Instruction::AShr:
63 case Instruction::LShr:
64 case Instruction::Shl:
65 case Instruction::UDiv:
66 case Instruction::URem: {
68 Processed);
70 Processed);
72 if (Opc == Instruction::LShr || Opc == Instruction::AShr)
74 break;
75 }
76 case Instruction::Trunc:
77 case Instruction::ZExt:
78 case Instruction::SExt:
79
80
81
82 if (I->getOperand(0)->getType() == Ty)
83 return I->getOperand(0);
84
85
86
88 Opc == Instruction::SExt);
89 break;
90 case Instruction::Select: {
92 IC, Processed);
94 IC, Processed);
96 break;
97 }
98 case Instruction::PHI: {
105 }
106 Res = NPN;
107 break;
108 }
109 case Instruction::FPToUI:
110 case Instruction::FPToSI:
112 I->getOperand(0), Ty);
113 break;
114 case Instruction::Call:
116 switch (II->getIntrinsicID()) {
117 default:
119 case Intrinsic::vscale: {
121 I->getModule(), Intrinsic::vscale, {Ty});
123 break;
124 }
125 }
126 }
127 break;
128 case Instruction::ShuffleVector: {
131 auto *FixedTy = VectorType::get(ScalarTy, VTy->getElementCount());
138 break;
139 }
140 default:
141
143 }
144
147
148
149
150 if (!V->hasOneUse())
151 Processed[V] = Result;
152
153 return Result;
154}
155
156
157
163
165InstCombinerImpl::isEliminableCastPair(const CastInst *CI1,
170
173 Type *SrcIntPtrTy =
175 Type *DstIntPtrTy =
178 DstTy, &DL);
179
180
181
182 if ((Res == Instruction::IntToPtr && SrcTy != DstIntPtrTy) ||
183 (Res == Instruction::PtrToInt && DstTy != SrcIntPtrTy))
184 Res = 0;
185
187}
188
189
193
197
198
201
202
203 auto *Res = CastInst::Create(NewOpc, CSrc->getOperand(0), Ty);
204
205 if (CSrc->hasOneUse())
207 return Res;
208 }
209 }
210
212
213
214
215
216
218 if (!Cmp || Cmp->getOperand(0)->getType() != Sel->getType() ||
219 (CI.getOpcode() == Instruction::Trunc &&
221
222
223
224 if (CI.getOpcode() != Instruction::BitCast ||
228 return NV;
229 }
230 }
231 }
232 }
233
234
236
237
238 if (!Src->getType()->isIntegerTy() || !CI.getType()->isIntegerTy() ||
241 return NV;
242 }
243
244
245
246
247
251
254 if (SrcTy && DestTy &&
255 SrcTy->getNumElements() == DestTy->getNumElements() &&
256 SrcTy->getPrimitiveSizeInBits() == DestTy->getPrimitiveSizeInBits()) {
259 }
260 }
261
262 return nullptr;
263}
264
265namespace {
266
267
268
269class TypeEvaluationHelper {
270public:
271
272
273
274 [[nodiscard]] static bool canEvaluateTruncated(Value *V, Type *Ty,
277
278
279
280 [[nodiscard]] static bool canEvaluateZExtd(Value *V, Type *Ty,
281 unsigned &BitsToClear,
284
285
286
287
288 [[nodiscard]] static bool canEvaluateSExtd(Value *V, Type *Ty);
289
290private:
291
292
293 [[nodiscard]] static bool canAlwaysEvaluateInType(Value *V, Type *Ty);
294
295
296 [[nodiscard]] bool allPendingVisited() const {
298 [this](Value *V) { return Visited.contains(V); });
299 }
300
301
302
303 [[nodiscard]] bool
305 llvm::function_ref<bool(Value *, Type *Type)> Pred) {
306 if (canAlwaysEvaluateInType(V, Ty))
307 return true;
308
310
311 if (I == nullptr)
312 return false;
313
314
315 const auto [It, Inserted] = Visited.insert({V, false});
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331 if (!Inserted)
332 return It->getSecond();
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393 if (->hasOneUse())
395
396 const bool Result = Pred(V, Ty);
397
398
401 }
402
403
404
405 [[nodiscard]] bool canNotEvaluateInType(Value *V, Type *Ty);
406
407 [[nodiscard]] bool canEvaluateTruncatedImpl(Value *V, Type *Ty,
408 InstCombinerImpl &IC,
409 Instruction *CxtI);
410 [[nodiscard]] bool canEvaluateTruncatedPred(Value *V, Type *Ty,
411 InstCombinerImpl &IC,
412 Instruction *CxtI);
413 [[nodiscard]] bool canEvaluateZExtdImpl(Value *V, Type *Ty,
414 unsigned &BitsToClear,
415 InstCombinerImpl &IC,
416 Instruction *CxtI);
417 [[nodiscard]] bool canEvaluateSExtdImpl(Value *V, Type *Ty);
418 [[nodiscard]] bool canEvaluateSExtdPred(Value *V, Type *Ty);
419
420
421
422 SmallDenseMap<Value *, bool, 8> Visited;
423
424
425 SmallVector<Value *, 8> Pending;
426};
427
428}
429
430
431
432bool TypeEvaluationHelper::canAlwaysEvaluateInType(Value *V, Type *Ty) {
435
438 X->getType() == Ty)
439 return true;
440
441 return false;
442}
443
444
445
446bool TypeEvaluationHelper::canNotEvaluateInType(Value *V, Type *Ty) {
448 return true;
449
450
451 if (->hasOneUse())
452 return true;
453
454 return false;
455}
456
457
458
459
460
461
462
463
464
465
466
467
468bool TypeEvaluationHelper::canEvaluateTruncated(Value *V, Type *Ty,
471 TypeEvaluationHelper TYH;
472 return TYH.canEvaluateTruncatedImpl(V, Ty, IC, CxtI) &&
473
474
475 TYH.allPendingVisited();
476}
477
478bool TypeEvaluationHelper::canEvaluateTruncatedImpl(Value *V, Type *Ty,
481 return canEvaluate(V, Ty, [this, &IC, CxtI](Value *V, Type *Ty) {
482 return canEvaluateTruncatedPred(V, Ty, IC, CxtI);
483 });
484}
485
486bool TypeEvaluationHelper::canEvaluateTruncatedPred(Value *V, Type *Ty,
490 Type *OrigTy = V->getType();
491 switch (I->getOpcode()) {
492 case Instruction::Add:
493 case Instruction::Sub:
494 case Instruction::Mul:
495 case Instruction::And:
496 case Instruction::Or:
497 case Instruction::Xor:
498
499 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&
500 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);
501
502 case Instruction::UDiv:
503 case Instruction::URem: {
504
507 assert(BitWidth < OrigBitWidth && "Unexpected bitwidths!");
509
510
513 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&
514 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);
515 }
516 break;
517 }
518 case Instruction::Shl: {
519
520
525 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&
526 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);
527 break;
528 }
529 case Instruction::LShr: {
530
531
532
533
534
541
542
544 auto DemandedBits = Trunc->getType()->getScalarSizeInBits();
546 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&
547 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);
548 }
550 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&
551 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);
552 }
553 break;
554 }
555 case Instruction::AShr: {
556
557
558
559
560
565 unsigned ShiftedBits = OrigBitWidth - BitWidth;
568 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&
569 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);
570 break;
571 }
572 case Instruction::Trunc:
573
574 return true;
575 case Instruction::ZExt:
576 case Instruction::SExt:
577
578
579 return true;
580 case Instruction::Select: {
582 return canEvaluateTruncatedImpl(SI->getTrueValue(), Ty, IC, CxtI) &&
583 canEvaluateTruncatedImpl(SI->getFalseValue(), Ty, IC, CxtI);
584 }
585 case Instruction::PHI: {
586
587
588
592 return canEvaluateTruncatedImpl(IncValue, Ty, IC, CxtI);
593 });
594 }
595 case Instruction::FPToUI:
596 case Instruction::FPToSI: {
597
598
599
603 Semantics, I->getOpcode() == Instruction::FPToSI);
605 }
606 case Instruction::ShuffleVector:
607 return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&
608 canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);
609
610 default:
611
612 break;
613 }
614
615 return false;
616}
617
618
619
620
621
622
623
629 return nullptr;
630
631 Value *VecInput = nullptr;
637 return nullptr;
638
640 unsigned VecWidth = VecType->getPrimitiveSizeInBits();
642 unsigned ShiftAmount = ShiftVal ? ShiftVal->getZExtValue() : 0;
643
644 if ((VecWidth % DestWidth != 0) || (ShiftAmount % DestWidth != 0))
645 return nullptr;
646
647
648
649 unsigned NumVecElts = VecWidth / DestWidth;
650 if (VecType->getElementType() != DestType) {
653 }
654
655 unsigned Elt = ShiftAmount / DestWidth;
657 Elt = NumVecElts - 1 - Elt;
658
660}
661
662
663
664
665
666
667
668
669
670
671
672
673
677 Type *SrcType = Src->getType();
679
680
681
683 unsigned DstBits = DstType->getScalarSizeInBits();
684 unsigned TruncRatio = SrcBits / DstBits;
685 if ((SrcBits % DstBits) != 0)
686 return nullptr;
687
690 const APInt *ShiftAmount = nullptr;
695 return nullptr;
696
698 auto VecElts = VecOpTy->getElementCount();
699
700 uint64_t BitCastNumElts = VecElts.getKnownMinValue() * TruncRatio;
703 ? (VecOpIdx + 1) * TruncRatio - 1
704 : VecOpIdx * TruncRatio;
705
706
707 if (ShiftAmount) {
708
709
710 if (ShiftAmount->uge(SrcBits) || ShiftAmount->urem(DstBits) != 0)
711 return nullptr;
712
715 : (NewIdx + IdxOfs);
716 }
717
718 assert(BitCastNumElts <= std::numeric_limits<uint32_t>::max() &&
719 NewIdx <= std::numeric_limits<uint32_t>::max() && "overflow 32-bits");
720
721 auto *BitCastTo =
722 VectorType::get(DstType, BitCastNumElts, VecElts.isScalable());
725}
726
727
728
732 "Don't narrow to an illegal scalar type");
733
734
735
740 return nullptr;
741
742
743
744 BinaryOperator *Or0, *Or1;
746 return nullptr;
747
748 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
752 return nullptr;
753
754
755 if (Or0->getOpcode() == BinaryOperator::LShr) {
759 }
761 Or1->getOpcode() == BinaryOperator::LShr &&
762 "Illegal or(shift,shift) pair");
763
764
765
766 auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * {
767
768
769
770
771 unsigned MaxShiftAmountWidth = Log2_32(NarrowWidth);
772 APInt HiBitMask = ~APInt::getLowBitsSet(WideWidth, MaxShiftAmountWidth);
775 return L;
776
777
778
779 if (ShVal0 != ShVal1)
780 return nullptr;
781
782
783
785 unsigned Mask = Width - 1;
788 return X;
789
790
793 return X;
794
795 return nullptr;
796 };
797
798 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, NarrowWidth);
799 bool IsFshl = true;
800 if (!ShAmt) {
801 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, NarrowWidth);
802 IsFshl = false;
803 }
804 if (!ShAmt)
805 return nullptr;
806
807
808
809
812 return nullptr;
813
814
815
816
817
818
819 Value *NarrowShAmt = Builder.CreateZExtOrTrunc(ShAmt, DestTy);
820
822 X = Y = Builder.CreateTrunc(ShVal0, DestTy);
823 if (ShVal0 != ShVal1)
824 Y = Builder.CreateTrunc(ShVal1, DestTy);
825 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
829}
830
831
832
838
839 if ((SrcTy) && !shouldChangeType(SrcTy, DestTy))
840 return nullptr;
841
842 BinaryOperator *BinOp;
844 return nullptr;
845
849 case Instruction::And:
850 case Instruction::Or:
851 case Instruction::Xor:
852 case Instruction::Add:
853 case Instruction::Sub:
854 case Instruction::Mul: {
857
859 Value *TruncX = Builder.CreateTrunc(BinOp1, DestTy);
861 }
863
865 Value *TruncX = Builder.CreateTrunc(BinOp0, DestTy);
867 }
870
871 Value *NarrowOp1 = Builder.CreateTrunc(BinOp1, DestTy);
873 }
875
876 Value *NarrowOp0 = Builder.CreateTrunc(BinOp0, DestTy);
878 }
879 break;
880 }
881 case Instruction::LShr:
882 case Instruction::AShr: {
883
887 unsigned MaxShiftAmt = SrcWidth - DestWidth;
888
889
891 APInt(SrcWidth, MaxShiftAmt)))) {
893 bool IsExact = OldShift->isExact();
895 true, DL)) {
898 OldShift->getOpcode() == Instruction::AShr
899 ? Builder.CreateAShr(A, ShAmt, OldShift->getName(), IsExact)
900 : Builder.CreateLShr(A, ShAmt, OldShift->getName(), IsExact);
902 }
903 }
904 }
905 break;
906 }
907 default: break;
908 }
909
910 if (Instruction *NarrowOr = narrowFunnelShift(Trunc))
911 return NarrowOr;
912
913 return nullptr;
914}
915
916
917
918
922 if (Shuf && Shuf->hasOneUse() && match(Shuf->getOperand(1), m_Undef()) &&
923 all_equal(Shuf->getShuffleMask()) &&
926 ->getElementCount())) {
927
928
931 Value *NarrowOp = Builder.CreateTrunc(Shuf->getOperand(0), NewTruncTy);
933 }
934
935 return nullptr;
936}
937
938
939
940
941
942
946 assert((Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) &&
947 "Unexpected instruction for shrinking");
948
950 if (!InsElt || !InsElt->hasOneUse())
951 return nullptr;
952
955 Value *VecOp = InsElt->getOperand(0);
956 Value *ScalarOp = InsElt->getOperand(1);
957 Value *Index = InsElt->getOperand(2);
958
960
961
963 Value *NarrowOp = Builder.CreateCast(Opcode, ScalarOp, DestScalarTy);
965 }
966
967 return nullptr;
968}
969
972 return Result;
973
975 Type *DestTy = Trunc.getType(), *SrcTy = Src->getType();
977 unsigned SrcWidth = SrcTy->getScalarSizeInBits();
978
979
980
981
982
983 if ((DestTy->isVectorTy() || shouldChangeType(SrcTy, DestTy)) &&
984 TypeEvaluationHelper::canEvaluateTruncated(Src, DestTy, *this, &Trunc)) {
985
986
987
989 dbgs() << "ICE: EvaluateInDifferentType converting expression type"
990 " to avoid cast: "
991 << Trunc << '\n');
995 }
996
997
998
999
1000
1002 if (DestWidth * 2 < SrcWidth) {
1003 auto *NewDestTy = DestITy->getExtendedType();
1004 if (shouldChangeType(SrcTy, NewDestTy) &&
1005 TypeEvaluationHelper::canEvaluateTruncated(Src, NewDestTy, *this,
1006 &Trunc)) {
1008 dbgs() << "ICE: EvaluateInDifferentType converting expression type"
1009 " to reduce the width of operand of"
1010 << Trunc << '\n');
1012 return new TruncInst(Res, DestTy);
1013 }
1014 }
1015 }
1016
1017
1018
1020 return &Trunc;
1021
1022 if (DestWidth == 1) {
1024
1026 const APInt *C1;
1030
1034 }
1035
1037
1038
1040 }
1041
1044
1045 Constant *One = ConstantInt::get(SrcTy, APInt(SrcWidth, 1));
1049 }
1052
1053 Constant *One = ConstantInt::get(SrcTy, APInt(SrcWidth, 1));
1057 }
1058
1059 {
1062
1064 }
1065 }
1066
1071 }
1072 }
1073
1077 unsigned AWidth = A->getType()->getScalarSizeInBits();
1078 unsigned MaxShiftAmt = SrcWidth - std::max(DestWidth, AWidth);
1080 bool IsExact = OldSh->isExact();
1081
1082
1083
1085 APInt(SrcWidth, MaxShiftAmt)))) {
1086 auto GetNewShAmt = [&](unsigned Width) {
1087 Constant *MaxAmt = ConstantInt::get(SrcTy, Width - 1, false);
1092 DL);
1093 };
1094
1095
1096 if (A->getType() == DestTy) {
1097 Constant *ShAmt = GetNewShAmt(DestWidth);
1099 return IsExact ? BinaryOperator::CreateExactAShr(A, ShAmt)
1100 : BinaryOperator::CreateAShr(A, ShAmt);
1101 }
1102
1103
1104 if (Src->hasOneUse()) {
1105 Constant *ShAmt = GetNewShAmt(AWidth);
1106 Value *Shift = Builder.CreateAShr(A, ShAmt, "", IsExact);
1108 }
1109 }
1110
1111 }
1112
1114 return I;
1115
1117 return I;
1118
1120 return I;
1121
1122 if (Src->hasOneUse() &&
1123 (isa(SrcTy) || shouldChangeType(SrcTy, DestTy))) {
1124
1125
1128
1129
1130 APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth);
1132 Value *NewTrunc = Builder.CreateTrunc(A, DestTy, A->getName() + ".tr");
1135 }
1136 }
1137 }
1138
1140 return I;
1141
1143 return I;
1144
1145
1148 unsigned AWidth = A->getType()->getScalarSizeInBits();
1149 if (AWidth == DestWidth && AWidth > Log2_32(SrcWidth)) {
1150 Value *WidthDiff = ConstantInt::get(A->getType(), SrcWidth - AWidth);
1151 Value *NarrowCtlz =
1152 Builder.CreateIntrinsic(Intrinsic::ctlz, {Trunc.getType()}, {A, B});
1153 return BinaryOperator::CreateAdd(NarrowCtlz, WidthDiff);
1154 }
1155 }
1156
1162 if (std::optional MaxVScale = Attr.getVScaleRangeMax())
1163 if (Log2_32(*MaxVScale) < DestWidth)
1165 }
1166 }
1167
1168 if (DestWidth == 1 &&
1172
1178 }
1181 &Trunc)) {
1184 }
1185
1186 const APInt *C1;
1188
1189
1193 }
1194
1195
1196
1197
1201 }
1202
1203
1204
1205
1209 }
1210
1211 return Changed ? &Trunc : nullptr;
1212}
1213
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226 const APInt *Op1CV;
1227 if (match(Cmp->getOperand(1), m_APInt(Op1CV))) {
1228
1229
1231 Value *In = Cmp->getOperand(0);
1232 Value *Sh = ConstantInt::get(In->getType(),
1233 In->getType()->getScalarSizeInBits() - 1);
1234 In = Builder.CreateLShr(In, Sh, In->getName() + ".lobit");
1235 if (In->getType() != Zext.getType())
1236 In = Builder.CreateIntCast(In, Zext.getType(), false );
1237
1239 }
1240
1241
1242
1243
1244
1245
1246 if (Op1CV->isZero() && Cmp->isEquality()) {
1247
1248
1250 APInt KnownZeroMask(~Known.Zero);
1251 uint32_t ShAmt = KnownZeroMask.logBase2();
1252 bool IsExpectShAmt = KnownZeroMask.isPowerOf2() &&
1254 if (IsExpectShAmt &&
1255 (Cmp->getOperand(0)->getType() == Zext.getType() ||
1257 Value *In = Cmp->getOperand(0);
1258 if (ShAmt) {
1259
1260
1261 In = Builder.CreateLShr(In, ConstantInt::get(In->getType(), ShAmt),
1262 In->getName() + ".lobit");
1263 }
1264
1265
1267 In = Builder.CreateXor(In, ConstantInt::get(In->getType(), 1));
1268
1269 if (Zext.getType() == In->getType())
1271
1274 }
1275 }
1276 }
1277
1278 if (Cmp->isEquality()) {
1279
1280
1281
1287 Value *Shift = And->getOperand(X == And->getOperand(0) ? 1 : 0);
1288 if (Zext.getType() == And->getType() ||
1294 Builder.CreateAnd(Lshr, ConstantInt::get(X->getType(), 1));
1296 Zext, Builder.CreateZExtOrTrunc(And1, Zext.getType()));
1297 }
1298 }
1299 }
1300
1301 return nullptr;
1302}
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322bool TypeEvaluationHelper::canEvaluateZExtd(Value *V, Type *Ty,
1323 unsigned &BitsToClear,
1326 TypeEvaluationHelper TYH;
1327 return TYH.canEvaluateZExtdImpl(V, Ty, BitsToClear, IC, CxtI);
1328}
1329bool TypeEvaluationHelper::canEvaluateZExtdImpl(Value *V, Type *Ty,
1330 unsigned &BitsToClear,
1333 BitsToClear = 0;
1334 if (canAlwaysEvaluateInType(V, Ty))
1335 return true;
1336
1337
1338 if (canNotEvaluateInType(V, Ty))
1339 return false;
1340
1342 unsigned Tmp;
1343 switch (I->getOpcode()) {
1344 case Instruction::ZExt:
1345 case Instruction::SExt:
1346 case Instruction::Trunc:
1347 return true;
1348 case Instruction::And:
1349 case Instruction::Or:
1350 case Instruction::Xor:
1351 case Instruction::Add:
1352 case Instruction::Sub:
1353 case Instruction::Mul:
1354 if (!canEvaluateZExtdImpl(I->getOperand(0), Ty, BitsToClear, IC, CxtI) ||
1355 !canEvaluateZExtdImpl(I->getOperand(1), Ty, Tmp, IC, CxtI))
1356 return false;
1357
1358 if (BitsToClear == 0 && Tmp == 0)
1359 return true;
1360
1361
1362
1363 if (Tmp == 0 && I->isBitwiseLogicOp()) {
1364
1365
1366 unsigned VSize = V->getType()->getScalarSizeInBits();
1369 CxtI)) {
1370
1371
1372 if (I->getOpcode() == Instruction::And)
1373 BitsToClear = 0;
1374 return true;
1375 }
1376 }
1377
1378
1379 return false;
1380
1381 case Instruction::Shl: {
1382
1383
1384 uint64_t ShiftAmt;
1386 if (!canEvaluateZExtdImpl(I->getOperand(0), Ty, BitsToClear, IC, CxtI))
1387 return false;
1388 BitsToClear = ShiftAmt < BitsToClear ? BitsToClear - ShiftAmt : 0;
1389 return true;
1390 }
1391 return false;
1392 }
1393 case Instruction::LShr: {
1394
1395
1396 uint64_t ShiftAmt;
1398 if (!canEvaluateZExtdImpl(I->getOperand(0), Ty, BitsToClear, IC, CxtI))
1399 return false;
1400 BitsToClear += ShiftAmt;
1401 if (BitsToClear > V->getType()->getScalarSizeInBits())
1402 BitsToClear = V->getType()->getScalarSizeInBits();
1403 return true;
1404 }
1405
1406 return false;
1407 }
1408 case Instruction::Select:
1409 if (!canEvaluateZExtdImpl(I->getOperand(1), Ty, Tmp, IC, CxtI) ||
1410 !canEvaluateZExtdImpl(I->getOperand(2), Ty, BitsToClear, IC, CxtI) ||
1411
1412
1413 Tmp != BitsToClear)
1414 return false;
1415 return true;
1416
1417 case Instruction::PHI: {
1418
1419
1420
1422 if (!canEvaluateZExtdImpl(PN->getIncomingValue(0), Ty, BitsToClear, IC,
1423 CxtI))
1424 return false;
1426 if (!canEvaluateZExtdImpl(PN->getIncomingValue(i), Ty, Tmp, IC, CxtI) ||
1427
1428
1429 Tmp != BitsToClear)
1430 return false;
1431 return true;
1432 }
1433 case Instruction::Call:
1434
1435
1437 if (II->getIntrinsicID() == Intrinsic::vscale)
1438 return true;
1439 return false;
1440 default:
1441
1442 return false;
1443 }
1444}
1445
1447
1448
1451 return nullptr;
1452
1453
1455 return Result;
1456
1458 Type *SrcTy = Src->getType(), *DestTy = Zext.getType();
1459
1460
1461 if (SrcTy->isIntOrIntVectorTy(1) && Zext.hasNonNeg())
1463
1464
1465 unsigned BitsToClear;
1466 if (shouldChangeType(SrcTy, DestTy) &&
1467 TypeEvaluationHelper::canEvaluateZExtd(Src, DestTy, BitsToClear, *this,
1468 &Zext)) {
1470 "Can't clear more bits than in SrcTy");
1471
1472
1474 dbgs() << "ICE: EvaluateInDifferentType converting expression type"
1475 " to avoid zero extend: "
1476 << Zext << '\n');
1479
1480
1482 if (SrcOp->hasOneUse())
1484
1485 uint32_t SrcBitsKept = SrcTy->getScalarSizeInBits() - BitsToClear;
1487
1488
1489
1492 &Zext))
1494
1495
1498 return BinaryOperator::CreateAnd(Res, C);
1499 }
1500
1501
1502
1503
1505
1506
1507
1508
1509 Value *A = CSrc->getOperand(0);
1510 unsigned SrcSize = A->getType()->getScalarSizeInBits();
1511 unsigned MidSize = CSrc->getType()->getScalarSizeInBits();
1513
1514
1515
1516
1517 if (SrcSize < DstSize) {
1519 Constant *AndConst = ConstantInt::get(A->getType(), AndValue);
1522 }
1523
1524 if (SrcSize == DstSize) {
1526 return BinaryOperator::CreateAnd(A, ConstantInt::get(A->getType(),
1527 AndValue));
1528 }
1529 if (SrcSize > DstSize) {
1532 return BinaryOperator::CreateAnd(Trunc,
1533 ConstantInt::get(Trunc->getType(),
1534 AndValue));
1535 }
1536 }
1537
1539 return transformZExtICmp(Cmp, Zext);
1540
1541
1545 X->getType() == DestTy)
1546 return BinaryOperator::CreateAnd(X, Builder.CreateZExt(C, DestTy));
1547
1548
1552 X->getType() == DestTy) {
1554 return BinaryOperator::CreateXor(Builder.CreateAnd(X, ZC), ZC);
1555 }
1556
1557
1558
1559
1560
1561
1563 X->getType() == DestTy) {
1565 return BinaryOperator::CreateAnd(X, ZextC);
1566 }
1567
1573 if (std::optional MaxVScale = Attr.getVScaleRangeMax()) {
1574 unsigned TypeWidth = Src->getType()->getScalarSizeInBits();
1575 if (Log2_32(*MaxVScale) < TypeWidth)
1577 }
1578 }
1579 }
1580
1582
1584 SrcTy->getScalarSizeInBits() >
1588 return &Zext;
1589 }
1590
1593 return &Zext;
1594 }
1595 }
1596
1597 return nullptr;
1598}
1599
1600
1603 Value *Op0 = Cmp->getOperand(0), *Op1 = Cmp->getOperand(1);
1605
1606
1607 if (!Op1->getType()->isIntOrIntVectorTy())
1608 return nullptr;
1609
1611
1612 Value *Sh = ConstantInt::get(Op0->getType(),
1614 Value *In = Builder.CreateAShr(Op0, Sh, Op0->getName() + ".lobit");
1615 if (In->getType() != Sext.getType())
1616 In = Builder.CreateIntCast(In, Sext.getType(), true );
1617
1619 }
1620
1622
1623
1624
1625 if (Cmp->hasOneUse() &&
1626 Cmp->isEquality() && (Op1C->isZero() || Op1C->getValue().isPowerOf2())){
1628
1629 APInt KnownZeroMask(~Known.Zero);
1630 if (KnownZeroMask.isPowerOf2()) {
1631 Value *In = Cmp->getOperand(0);
1632
1633
1634 if (!Op1C->isZero() && Op1C->getValue() != KnownZeroMask) {
1639 }
1640
1642
1643
1644 unsigned ShiftAmt = KnownZeroMask.countr_zero();
1645
1646 if (ShiftAmt)
1648 ConstantInt::get(In->getType(), ShiftAmt));
1649
1650
1651
1654 "sext");
1655 } else {
1656
1657
1658 unsigned ShiftAmt = KnownZeroMask.countl_zero();
1659
1660 if (ShiftAmt)
1662 ConstantInt::get(In->getType(), ShiftAmt));
1663
1664
1665 In = Builder.CreateAShr(In, ConstantInt::get(In->getType(),
1666 KnownZeroMask.getBitWidth() - 1), "sext");
1667 }
1668
1669 if (Sext.getType() == In->getType())
1672 }
1673 }
1674 }
1675
1676 return nullptr;
1677}
1678
1679
1680
1681
1682
1683
1684
1685
1686bool TypeEvaluationHelper::canEvaluateSExtd(Value *V, Type *Ty) {
1687 TypeEvaluationHelper TYH;
1688 return TYH.canEvaluateSExtdImpl(V, Ty) && TYH.allPendingVisited();
1689}
1690
1691bool TypeEvaluationHelper::canEvaluateSExtdImpl(Value *V, Type *Ty) {
1692 return canEvaluate(V, Ty, [this](Value *V, Type *Ty) {
1693 return canEvaluateSExtdPred(V, Ty);
1694 });
1695}
1696
1697bool TypeEvaluationHelper::canEvaluateSExtdPred(Value *V, Type *Ty) {
1699 "Can't sign extend type to a smaller type");
1700
1702 switch (I->getOpcode()) {
1703 case Instruction::SExt:
1704 case Instruction::ZExt:
1705 case Instruction::Trunc:
1706 return true;
1707 case Instruction::And:
1708 case Instruction::Or:
1709 case Instruction::Xor:
1710 case Instruction::Add:
1711 case Instruction::Sub:
1712 case Instruction::Mul:
1713
1714 return canEvaluateSExtdImpl(I->getOperand(0), Ty) &&
1715 canEvaluateSExtdImpl(I->getOperand(1), Ty);
1716
1717
1718
1719
1720 case Instruction::Select:
1721 return canEvaluateSExtdImpl(I->getOperand(1), Ty) &&
1722 canEvaluateSExtdImpl(I->getOperand(2), Ty);
1723
1724 case Instruction::PHI: {
1725
1726
1727
1730 if (!canEvaluateSExtdImpl(IncValue, Ty))
1731 return false;
1732 return true;
1733 }
1734 default:
1735
1736 break;
1737 }
1738
1739 return false;
1740}
1741
1743
1744
1746 return nullptr;
1747
1749 return I;
1750
1752 Type *SrcTy = Src->getType(), *DestTy = Sext.getType();
1755
1756
1759 CI->setNonNeg(true);
1760 return CI;
1761 }
1762
1763
1764 bool ShouldExtendExpression = true;
1765 Value *TruncSrc = nullptr;
1766
1767
1770 ShouldExtendExpression = false;
1771 if (ShouldExtendExpression && shouldChangeType(SrcTy, DestTy) &&
1772 TypeEvaluationHelper::canEvaluateSExtd(Src, DestTy)) {
1773
1775 dbgs() << "ICE: EvaluateInDifferentType converting expression type"
1776 " to avoid sign extend: "
1777 << Sext << '\n');
1780
1781
1782
1785
1786
1787 Value *ShAmt = ConstantInt::get(DestTy, DestBitSize - SrcBitSize);
1788 return BinaryOperator::CreateAShr(Builder.CreateShl(Res, ShAmt, "sext"),
1789 ShAmt);
1790 }
1791
1793 if (X) {
1794
1795
1796 unsigned XBitSize = X->getType()->getScalarSizeInBits();
1801 ResTrunc->setHasNoSignedWrap(true);
1802 return Res;
1803 }
1804
1805
1806 if (Src->hasOneUse() && X->getType() == DestTy) {
1807
1808 Constant *ShAmt = ConstantInt::get(DestTy, DestBitSize - SrcBitSize);
1809 return BinaryOperator::CreateAShr(Builder.CreateShl(X, ShAmt), ShAmt);
1810 }
1811
1812
1813
1814
1815
1817 if (Src->hasOneUse() &&
1820 Value *Ashr = Builder.CreateAShr(Y, XBitSize - SrcBitSize);
1822 }
1823 }
1824
1826 return transformSExtICmp(Cmp, Sext);
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1842
1843 Constant *BA = nullptr, *CA = nullptr;
1849 assert(WideCurrShAmt && "Constant folding of ImmConstant cannot fail");
1854 NumLowbitsLeft);
1855 NewShAmt =
1858 return BinaryOperator::CreateAShr(A, NewShAmt);
1859 }
1860
1861
1862
1863
1866 Type *XTy = X->getType();
1868 Constant *ShlAmtC = ConstantInt::get(XTy, XBitSize - SrcBitSize);
1869 Constant *AshrAmtC = ConstantInt::get(XTy, XBitSize - 1);
1870 if (XTy == DestTy)
1871 return BinaryOperator::CreateAShr(Builder.CreateShl(X, ShlAmtC),
1872 AshrAmtC);
1876 }
1877 }
1878
1884 if (std::optional MaxVScale = Attr.getVScaleRangeMax())
1885 if (Log2_32(*MaxVScale) < (SrcBitSize - 1))
1887 }
1888 }
1889
1890 return nullptr;
1891}
1892
1893
1894
1896 bool losesInfo;
1898 return !losesInfo;
1899}
1900
1902 bool PreferBFloat) {
1903
1906
1909
1913 return nullptr;
1914
1917
1918 return nullptr;
1919}
1920
1923 if (Ty->getScalarType()->isPPC_FP128Ty())
1924 return nullptr;
1925
1926 Type *ShrinkTy =
1928 if (ShrinkTy)
1931
1932 return ShrinkTy;
1933}
1934
1935
1936
1940 if (!CV || !CVVTy)
1941 return nullptr;
1942
1943 Type *MinType = nullptr;
1944
1945 unsigned NumElts = CVVTy->getNumElements();
1946
1947
1948
1949 for (unsigned i = 0; i != NumElts; ++i) {
1951 continue;
1952
1954 if (!CFP)
1955 return nullptr;
1956
1958 if ()
1959 return nullptr;
1960
1961
1962
1963 if (!MinType || T->getFPMantissaWidth() > MinType->getFPMantissaWidth())
1964 MinType = T;
1965 }
1966
1967
1969}
1970
1971
1974 return FPExt->getOperand(0)->getType();
1975
1976
1977
1978
1981 return T;
1982
1983
1989
1990
1991
1993 return T;
1994
1995 return V->getType();
1996}
1997
1998
1999
2002 assert((Opcode == CastInst::SIToFP || Opcode == CastInst::UIToFP) &&
2003 "Unexpected cast");
2004 Value *Src = I.getOperand(0);
2005 Type *SrcTy = Src->getType();
2006 Type *FPTy = I.getType();
2007 bool IsSigned = Opcode == Instruction::SIToFP;
2008 int SrcSize = (int)SrcTy->getScalarSizeInBits() - IsSigned;
2009
2010
2011
2013 if (SrcSize <= DestNumSigBits)
2014 return true;
2015
2016
2017
2020
2021
2022 int SrcNumSigBits = F->getType()->getFPMantissaWidth();
2024 SrcNumSigBits++;
2025
2026
2027
2028
2029 if (SrcNumSigBits > 0 && DestNumSigBits > 0 &&
2030 SrcNumSigBits <= DestNumSigBits)
2031 return true;
2032 }
2033
2034
2035
2036
2038 int SigBits = (int)SrcTy->getScalarSizeInBits() -
2041 if (SigBits <= DestNumSigBits)
2042 return true;
2043
2044 return false;
2045}
2046
2049 return I;
2050
2051
2052
2053
2054
2055
2056
2057
2060 if (BO && BO->hasOneUse()) {
2061 bool PreferBFloat = Ty->getScalarType()->isBFloatTy();
2064 unsigned OpWidth = BO->getType()->getFPMantissaWidth();
2067 unsigned SrcWidth = std::max(LHSWidth, RHSWidth);
2068 unsigned DstWidth = Ty->getFPMantissaWidth();
2069 switch (BO->getOpcode()) {
2070 default: break;
2071 case Instruction::FAdd:
2072 case Instruction::FSub:
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091 if (OpWidth >= 2*DstWidth+1 && DstWidth >= SrcWidth) {
2092 Value *LHS = Builder.CreateFPTrunc(BO->getOperand(0), Ty);
2093 Value *RHS = Builder.CreateFPTrunc(BO->getOperand(1), Ty);
2096 return RI;
2097 }
2098 break;
2099 case Instruction::FMul:
2100
2101
2102
2103
2104
2105 if (OpWidth >= LHSWidth + RHSWidth && DstWidth >= SrcWidth) {
2106 Value *LHS = Builder.CreateFPTrunc(BO->getOperand(0), Ty);
2107 Value *RHS = Builder.CreateFPTrunc(BO->getOperand(1), Ty);
2109 }
2110 break;
2111 case Instruction::FDiv:
2112
2113
2114
2115
2116
2117
2118 if (OpWidth >= 2*DstWidth && DstWidth >= SrcWidth) {
2119 Value *LHS = Builder.CreateFPTrunc(BO->getOperand(0), Ty);
2120 Value *RHS = Builder.CreateFPTrunc(BO->getOperand(1), Ty);
2122 }
2123 break;
2124 case Instruction::FRem: {
2125
2126
2127
2128
2129 if (SrcWidth == OpWidth)
2130 break;
2131 Value *LHS, *RHS;
2132 if (LHSWidth == SrcWidth) {
2133 LHS = Builder.CreateFPTrunc(BO->getOperand(0), LHSMinType);
2134 RHS = Builder.CreateFPTrunc(BO->getOperand(1), LHSMinType);
2135 } else {
2136 LHS = Builder.CreateFPTrunc(BO->getOperand(0), RHSMinType);
2137 RHS = Builder.CreateFPTrunc(BO->getOperand(1), RHSMinType);
2138 }
2139
2140 Value *ExactResult = Builder.CreateFRemFMF(LHS, RHS, BO);
2142 }
2143 }
2144 }
2145
2146
2149 if (Op && Op->hasOneUse()) {
2152 FMF &= FPMO->getFastMathFlags();
2153
2155 Value *InnerTrunc = Builder.CreateFPTruncFMF(X, Ty, FMF);
2156 Value *Neg = Builder.CreateFNegFMF(InnerTrunc, FMF);
2158 }
2159
2160
2161
2164 X->getType() == Ty) {
2165
2166 Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);
2168 Builder.CreateSelectFMF(Cond, X, NarrowY, FMF, "narrow.sel", Op);
2170 }
2172 X->getType() == Ty) {
2173
2174 Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);
2176 Builder.CreateSelectFMF(Cond, NarrowY, X, FMF, "narrow.sel", Op);
2178 }
2179 }
2180
2182 switch (II->getIntrinsicID()) {
2183 default: break;
2184 case Intrinsic::ceil:
2185 case Intrinsic::fabs:
2186 case Intrinsic:🤣
2187 case Intrinsic::nearbyint:
2188 case Intrinsic::rint:
2189 case Intrinsic::round:
2190 case Intrinsic::roundeven:
2191 case Intrinsic::trunc: {
2192 Value *Src = II->getArgOperand(0);
2193 if (!Src->hasOneUse())
2194 break;
2195
2196
2197
2198
2199 if (II->getIntrinsicID() != Intrinsic::fabs) {
2201 if (!FPExtSrc || FPExtSrc->getSrcTy() != Ty)
2202 break;
2203 }
2204
2205
2206
2207 Value *InnerTrunc = Builder.CreateFPTrunc(Src, Ty);
2209 FPT.getModule(), II->getIntrinsicID(), Ty);
2211 II->getOperandBundlesAsDefs(OpBundles);
2214
2215
2217 return NewCI;
2218 }
2219 }
2220 }
2221
2223 return I;
2224
2229 return CastInst::Create(FPCast->getOpcode(), FPCast->getOperand(0), Ty);
2230 }
2231
2232 return nullptr;
2233}
2234
2236
2237
2243 return CastInst::Create(FPCast->getOpcode(), FPCast->getOperand(0), Ty);
2244 }
2245
2247}
2248
2249
2250
2251
2252
2255 return nullptr;
2256
2258 Value *X = OpI->getOperand(0);
2259 Type *XType = X->getType();
2262
2263
2264
2265
2266
2267
2268
2270
2271
2272
2273
2274
2276 if (OutputSize > OpI->getType()->getFPMantissaWidth())
2277 return nullptr;
2278 }
2279
2282 if (IsInputSigned && IsOutputSigned)
2283 return new SExtInst(X, DestType);
2284 return new ZExtInst(X, DestType);
2285 }
2288
2289 assert(XType == DestType && "Unexpected types for int to FP to int casts");
2291}
2292
2294
2301
2302 return nullptr;
2303}
2304
2307 return I;
2308
2310 return I;
2311
2313}
2314
2317 return I;
2318
2320 return I;
2321
2323}
2324
2327 return R;
2330 return &CI;
2331 }
2332 return nullptr;
2333}
2334
2337 return R;
2339 auto *UI =
2341 UI->setNonNeg(true);
2342 return UI;
2343 }
2344 return nullptr;
2345}
2346
2348
2349
2350
2353 DL.getPointerSizeInBits(AS)) {
2358 }
2359
2360
2361
2362
2365 auto UsesPointerAsInt = [](User *U) {
2367 return true;
2370 return false;
2371 };
2376 Base->getType()->getPointerAddressSpace() &&
2379 }
2380
2382 return I;
2383
2384 return nullptr;
2385}
2386
2388
2391 while (true) {
2393 if ( ||
->hasOneUse())
2394 break;
2396 Ptr = GEP->getPointerOperand();
2397 }
2398
2399
2400 if (GEPs.empty() || PtrTy != Ptr->getType())
2401 return nullptr;
2402
2403
2405 Type *IdxTy = DL.getIndexType(PtrTy);
2407 Res->getType() == IntTy && IntTy == IdxTy) {
2408
2411 } else {
2412 return nullptr;
2413 }
2414
2415
2418 Res = Builder.CreateAdd(Res, Offset, "", GEP->hasNoUnsignedWrap());
2419 }
2420 return Builder.CreateZExtOrTrunc(Res, IntTy);
2421}
2422
2424
2425
2426
2431 unsigned TySize = Ty->getScalarSizeInBits();
2432 unsigned PtrSize = DL.getPointerSizeInBits(AS);
2433 if (TySize != PtrSize) {
2434 Type *IntPtrTy =
2438 }
2439
2440
2441
2442
2443 Value *Ptr, *Mask;
2446 Mask->getType() == Ty)
2447 return BinaryOperator::CreateAnd(Builder.CreatePtrToInt(Ptr, Ty), Mask);
2448
2451
2452 Value *Vec, *Scalar, *Index;
2457
2458
2459 Value *NewCast = Builder.CreatePtrToInt(Scalar, Ty->getScalarType());
2461 }
2462
2464}
2465
2469
2470
2471
2472
2473 Value *Ptr, *Mask;
2476 Mask->getType() == Ty)
2477 return BinaryOperator::CreateAnd(Builder.CreatePtrToAddr(Ptr), Mask);
2478
2481
2482
2484}
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2505
2506
2507
2509
2510 if (SrcTy->getElementType() != DestTy->getElementType()) {
2511
2512
2513
2514
2515 if (SrcTy->getElementType()->getPrimitiveSizeInBits() !=
2516 DestTy->getElementType()->getPrimitiveSizeInBits())
2517 return nullptr;
2518
2519 SrcTy =
2523 }
2524
2528
2529 assert(SrcElts != DestElts && "Element counts should be different.");
2530
2531
2532
2533
2537
2538 if (SrcElts > DestElts) {
2539
2540
2541
2542
2544
2545
2546
2547 ShuffleMask = ShuffleMaskStorage;
2548 if (IsBigEndian)
2549 ShuffleMask = ShuffleMask.take_back(DestElts);
2550 else
2551 ShuffleMask = ShuffleMask.take_front(DestElts);
2552 } else {
2553
2554
2555
2557
2559
2560
2561
2562 unsigned DeltaElts = DestElts - SrcElts;
2563 if (IsBigEndian)
2564 ShuffleMaskStorage.insert(ShuffleMaskStorage.begin(), DeltaElts, NullElt);
2565 else
2566 ShuffleMaskStorage.append(DeltaElts, NullElt);
2567 ShuffleMask = ShuffleMaskStorage;
2568 }
2569
2571}
2572
2574 return Value % Ty->getPrimitiveSizeInBits() == 0;
2575}
2576
2578 return Value / Ty->getPrimitiveSizeInBits();
2579}
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2595 "Shift should be a multiple of the element type size");
2596
2597
2599
2600
2601
2602 if (V->getType() == VecEltTy) {
2603
2605 if (C->isNullValue())
2606 return true;
2607
2610 ElementIndex = Elements.size() - ElementIndex - 1;
2611
2612
2613 if (Elements[ElementIndex])
2614 return false;
2615
2616 Elements[ElementIndex] = V;
2617 return true;
2618 }
2619
2621
2622
2623 unsigned NumElts = getTypeSizeIndex(C->getType()->getPrimitiveSizeInBits(),
2624 VecEltTy);
2625
2626
2627 if (NumElts == 1)
2629 Shift, Elements, VecEltTy, isBigEndian);
2630
2631
2632
2635 C->getType()->getPrimitiveSizeInBits()));
2638
2639 for (unsigned i = 0; i != NumElts; ++i) {
2640 unsigned ShiftI = i * ElementSize;
2642 Instruction::LShr, C, ConstantInt::get(C->getType(), ShiftI));
2643 if (!Piece)
2644 return false;
2645
2649 return false;
2650 }
2651 return true;
2652 }
2653
2654 if (!V->hasOneUse()) return false;
2655
2657 if () return false;
2658 switch (I->getOpcode()) {
2659 default: return false;
2660 case Instruction::BitCast:
2661 if (I->getOperand(0)->getType()->isVectorTy())
2662 return false;
2665 case Instruction::ZExt:
2667 I->getOperand(0)->getType()->getPrimitiveSizeInBits(),
2668 VecEltTy))
2669 return false;
2672 case Instruction::Or:
2677 case Instruction::Shl: {
2678
2680 if (!CI) return false;
2685 }
2686
2687 }
2688}
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2709
2710
2711
2713 return nullptr;
2714
2717 DestVecTy->getElementType(),
2719 return nullptr;
2720
2721
2722
2723
2725 for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
2726 if (!Elements[i]) continue;
2727
2730 }
2731
2732 return Result;
2733}
2734
2735
2736
2737
2738
2741 Value *VecOp, *Index;
2744 return nullptr;
2745
2746
2747
2754 }
2755
2756
2757
2759 if (DestType->isVectorTy() && FixedVType && FixedVType->getNumElements() == 1)
2760 return CastInst::Create(Instruction::BitCast, VecOp, DestType);
2761
2762 return nullptr;
2763}
2764
2765
2770
2773 return nullptr;
2774
2775
2776
2777
2779 return nullptr;
2780
2783
2786 if (X->getType()->isFPOrFPVectorTy() &&
2787 Y->getType()->isIntOrIntVectorTy()) {
2788 Value *CastedOp =
2789 Builder.CreateBitCast(BO->getOperand(0), Y->getType());
2790 Value *NewBO = Builder.CreateBinOp(BO->getOpcode(), CastedOp, Y);
2792 }
2793 if (X->getType()->isIntOrIntVectorTy() &&
2794 Y->getType()->isFPOrFPVectorTy()) {
2795 Value *CastedOp =
2796 Builder.CreateBitCast(BO->getOperand(1), X->getType());
2797 Value *NewBO = Builder.CreateBinOp(BO->getOpcode(), CastedOp, X);
2799 }
2800 }
2801 return nullptr;
2802 }
2803
2805 return nullptr;
2806
2810
2811 Value *CastedOp1 = Builder.CreateBitCast(BO->getOperand(1), DestTy);
2813 }
2814
2817
2818 Value *CastedOp0 = Builder.CreateBitCast(BO->getOperand(0), DestTy);
2820 }
2821
2822
2823
2824
2825
2828
2829 Value *CastedOp0 = Builder.CreateBitCast(BO->getOperand(0), DestTy);
2830 Value *CastedC = Builder.CreateBitCast(C, DestTy);
2832 }
2833
2834 return nullptr;
2835}
2836
2837
2843 return nullptr;
2844
2845
2846 Type *CondTy = Cond->getType();
2850 CondVTy->getElementCount() !=
2852 return nullptr;
2853
2854
2855
2856
2857
2859 return nullptr;
2860
2865
2866 Value *CastedVal = Builder.CreateBitCast(FVal, DestTy);
2868 }
2869
2872
2873 Value *CastedVal = Builder.CreateBitCast(TVal, DestTy);
2875 }
2876
2877 return nullptr;
2878}
2879
2880
2884 return false;
2885 }
2886 return true;
2887}
2888
2889
2890
2891
2892
2893
2894
2895
2896
2899
2901 return nullptr;
2902
2904 Type *SrcTy = Src->getType();
2906
2908 SmallSetVector<PHINode *, 4> OldPhiNodes;
2909
2910
2911
2912
2913
2915 OldPhiNodes.insert(PN);
2916 while (!PhiWorklist.empty()) {
2918 for (Value *IncValue : OldPN->incoming_values()) {
2920 continue;
2921
2923
2924
2925
2926
2927 Value *Addr = LI->getOperand(0);
2929 return nullptr;
2930
2931
2932
2933
2935 return nullptr;
2936 if (LI->hasOneUse() && LI->isSimple())
2937 continue;
2938
2939
2940 return nullptr;
2941 }
2942
2944 if (OldPhiNodes.insert(PNode))
2946 continue;
2947 }
2948
2950
2951 if (!BCI)
2952 return nullptr;
2953
2954
2955 Type *TyA = BCI->getOperand(0)->getType();
2956 Type *TyB = BCI->getType();
2957 if (TyA != DestTy || TyB != SrcTy)
2958 return nullptr;
2959 }
2960 }
2961
2962
2963
2964 for (auto *OldPN : OldPhiNodes) {
2965 for (User *V : OldPN->users()) {
2967 if (->isSimple() || SI->getOperand(0) != OldPN)
2968 return nullptr;
2970
2971 Type *TyB = BCI->getOperand(0)->getType();
2972 Type *TyA = BCI->getType();
2973 if (TyA != DestTy || TyB != SrcTy)
2974 return nullptr;
2976
2977
2978
2979 if (!OldPhiNodes.contains(PHI))
2980 return nullptr;
2981 } else {
2982 return nullptr;
2983 }
2984 }
2985 }
2986
2987
2988 SmallDenseMap<PHINode *, PHINode *> NewPNodes;
2989 for (auto *OldPN : OldPhiNodes) {
2990 Builder.SetInsertPoint(OldPN);
2991 PHINode *NewPN = Builder.CreatePHI(DestTy, OldPN->getNumOperands());
2992 NewPNodes[OldPN] = NewPN;
2993 }
2994
2995
2996 for (auto *OldPN : OldPhiNodes) {
2997 PHINode *NewPN = NewPNodes[OldPN];
2998 for (unsigned j = 0, e = OldPN->getNumOperands(); j != e; ++j) {
2999 Value *V = OldPN->getOperand(j);
3000 Value *NewV = nullptr;
3004
3005
3006 Builder.SetInsertPoint(LI);
3008
3009
3013 NewV = BCI->getOperand(0);
3015 NewV = NewPNodes[PrevPN];
3016 }
3018 NewPN->addIncoming(NewV, OldPN->getIncomingBlock(j));
3019 }
3020 }
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3032 for (auto *OldPN : OldPhiNodes) {
3033 PHINode *NewPN = NewPNodes[OldPN];
3036 assert(SI->isSimple() && SI->getOperand(0) == OldPN);
3037 Builder.SetInsertPoint(SI);
3038 auto *NewBC =
3040 SI->setOperand(0, NewBC);
3043 }
3045 Type *TyB = BCI->getOperand(0)->getType();
3046 Type *TyA = BCI->getType();
3047 assert(TyA == DestTy && TyB == SrcTy);
3048 (void) TyA;
3049 (void) TyB;
3051 if (BCI == &CI)
3052 RetVal = I;
3054 assert(OldPhiNodes.contains(PHI));
3055 (void) PHI;
3056 } else {
3058 }
3059 }
3060 }
3061
3062 return RetVal;
3063}
3064
3065
3066
3073 return nullptr;
3077 return nullptr;
3078 if (X->getType() != FTy)
3079 return nullptr;
3081 return nullptr;
3082
3083 return Builder.CreateCopySign(Builder.CreateBitCast(Y, FTy), X);
3084}
3085
3087
3088
3090 Type *SrcTy = Src->getType();
3092
3093
3094
3095 if (DestTy == Src->getType())
3097
3100
3101
3102
3109 return I;
3110 }
3111
3112
3113
3114
3117 }
3118 }
3119
3121 if (SrcVTy->getNumElements() == 1) {
3122
3123
3126 Builder.CreateExtractElement(Src,
3128 return CastInst::Create(Instruction::BitCast, Elem, DestTy);
3129 }
3130
3131
3132
3133
3135 return new BitCastInst(InsElt->getOperand(1), DestTy);
3136 }
3137
3138
3144 DestTy->isIntegerTy() && X->getType() == DestTy &&
3145 Y->getType()->isIntegerTy() && isDesirableIntType(BitWidth)) {
3146
3147 if (DL.isBigEndian())
3148 IndexC = SrcVTy->getNumElements() - 1 - IndexC;
3149
3150
3151
3152 if (IndexC == 0) {
3153
3154 unsigned EltWidth = Y->getType()->getScalarSizeInBits();
3158 return BinaryOperator::CreateOr(AndX, ZextY);
3159 }
3160 }
3161 }
3162
3164
3165
3166 Value *ShufOp0 = Shuf->getOperand(0);
3167 Value *ShufOp1 = Shuf->getOperand(1);
3168 auto ShufElts = cast(Shuf->getType())->getElementCount();
3170 if (Shuf->hasOneUse() && DestTy->isVectorTy() &&
3172 ShufElts == SrcVecElts) {
3174
3175
3176
3181 Value *LHS = Builder.CreateBitCast(ShufOp0, DestTy);
3182 Value *RHS = Builder.CreateBitCast(ShufOp1, DestTy);
3183
3184
3186 }
3187 }
3188
3189
3190
3191
3192
3193 if (DestTy->isIntegerTy() && ShufElts.getKnownMinValue() % 2 == 0 &&
3194 Shuf->hasOneUse() && Shuf->isReverse()) {
3195 unsigned IntrinsicNum = 0;
3197 SrcTy->getScalarSizeInBits() == 8) {
3198 IntrinsicNum = Intrinsic::bswap;
3199 } else if (SrcTy->getScalarSizeInBits() == 1) {
3200 IntrinsicNum = Intrinsic::bitreverse;
3201 }
3202 if (IntrinsicNum != 0) {
3203 assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask");
3206 CI.getModule(), IntrinsicNum, DestTy);
3207 Value *ScalarX = Builder.CreateBitCast(ShufOp0, DestTy);
3209 }
3210 }
3211 }
3212
3213
3215 if (Instruction *I = optimizeBitCastFromPhi(CI, PN))
3216 return I;
3217
3219 return I;
3220
3222 return I;
3223
3225 return I;
3226
3229
3231}
3232
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static std::optional< bool > isBigEndian(const SmallDenseMap< int64_t, int64_t, 8 > &MemOffset2Idx, int64_t LowestIdx)
Given a map from byte offsets in memory to indices in a load/store, determine if that map corresponds...
This file defines the DenseMap class.
static bool isSigned(unsigned int Opcode)
static bool collectInsertionElements(Value *V, unsigned Shift, SmallVectorImpl< Value * > &Elements, Type *VecEltTy, bool isBigEndian)
V is a value which is inserted into a vector of VecEltTy.
Definition InstCombineCasts.cpp:2591
static bool hasStoreUsersOnly(CastInst &CI)
Check if all users of CI are StoreInsts.
Definition InstCombineCasts.cpp:2881
static Value * foldCopySignIdioms(BitCastInst &CI, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
Fold (bitcast (or (and (bitcast X to int), signmask), nneg Y) to fp) to copysign((bitcast Y to fp),...
Definition InstCombineCasts.cpp:3067
static Type * shrinkFPConstantVector(Value *V, bool PreferBFloat)
Definition InstCombineCasts.cpp:1937
static Instruction * canonicalizeBitCastExtElt(BitCastInst &BitCast, InstCombinerImpl &IC)
Canonicalize scalar bitcasts of extracted elements into a bitcast of the vector followed by extract e...
Definition InstCombineCasts.cpp:2739
static Instruction * shrinkSplatShuffle(TruncInst &Trunc, InstCombiner::BuilderTy &Builder)
Try to narrow the width of a splat shuffle.
Definition InstCombineCasts.cpp:919
static Instruction * foldFPtoI(Instruction &FI, InstCombiner &IC)
Definition InstCombineCasts.cpp:2293
static Instruction * foldBitCastSelect(BitCastInst &BitCast, InstCombiner::BuilderTy &Builder)
Change the type of a select if we can eliminate a bitcast.
Definition InstCombineCasts.cpp:2838
static Instruction * foldBitCastBitwiseLogic(BitCastInst &BitCast, InstCombiner::BuilderTy &Builder)
Change the type of a bitwise logic operation if we can eliminate a bitcast.
Definition InstCombineCasts.cpp:2766
static bool fitsInFPType(APFloat F, const fltSemantics &Sem)
Return a Constant* for the specified floating-point constant if it fits in the specified FP type with...
Definition InstCombineCasts.cpp:1895
static Instruction * optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy, InstCombinerImpl &IC)
This input value (which is known to have vector type) is being zero extended or truncated to the spec...
Definition InstCombineCasts.cpp:2503
static Instruction * shrinkInsertElt(CastInst &Trunc, InstCombiner::BuilderTy &Builder)
Try to narrow the width of an insert element.
Definition InstCombineCasts.cpp:943
static Type * getMinimumFPType(Value *V, bool PreferBFloat)
Find the minimum FP type we can safely truncate to.
Definition InstCombineCasts.cpp:1972
SmallDenseMap< Value *, Value *, 8 > EvaluatedMap
Definition InstCombineCasts.cpp:37
static bool isMultipleOfTypeSize(unsigned Value, Type *Ty)
Definition InstCombineCasts.cpp:2573
static Value * optimizeIntegerToVectorInsertions(BitCastInst &CI, InstCombinerImpl &IC)
If the input is an 'or' instruction, we may be doing shifts and ors to assemble the elements of the v...
Definition InstCombineCasts.cpp:2705
static Type * shrinkFPConstant(LLVMContext &Ctx, const APFloat &F, bool PreferBFloat)
Definition InstCombineCasts.cpp:1901
static Instruction * foldVecExtTruncToExtElt(TruncInst &Trunc, InstCombinerImpl &IC)
Whenever an element is extracted from a vector, optionally shifted down, and then truncated,...
Definition InstCombineCasts.cpp:674
static Value * EvaluateInDifferentTypeImpl(Value *V, Type *Ty, bool isSigned, InstCombinerImpl &IC, EvaluatedMap &Processed)
Definition InstCombineCasts.cpp:39
static bool isKnownExactCastIntToFP(CastInst &I, InstCombinerImpl &IC)
Return true if the cast from integer to FP can be proven to be exact for all possible inputs (the con...
Definition InstCombineCasts.cpp:2000
static unsigned getTypeSizeIndex(unsigned Value, Type *Ty)
Definition InstCombineCasts.cpp:2577
static Instruction * foldVecTruncToExtElt(TruncInst &Trunc, InstCombinerImpl &IC)
Given a vector that is bitcast to an integer, optionally logically right-shifted, and truncated,...
Definition InstCombineCasts.cpp:624
This file provides internal interfaces used to implement the InstCombine.
This file provides the interface for the instcombine pass implementation.
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
static unsigned getScalarSizeInBits(Type *Ty)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static SymbolRef::Type getType(const Symbol *Sym)
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
static LLVM_ABI unsigned int semanticsIntSizeInBits(const fltSemantics &, bool)
Class for arbitrary precision integers.
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
uint64_t getZExtValue() const
Get zero extended value.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
LLVM_ABI APInt urem(const APInt &RHS) const
Unsigned remainder operation.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
int32_t exactLogBase2() const
unsigned countr_zero() const
Count the number of trailing zero bits.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
unsigned countr_one() const
Count the number of trailing one bits.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
This class represents a conversion between pointers from one address space to another.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const
Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static BinaryOperator * CreateFMulFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")
static BinaryOperator * CreateFDivFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This is the base class for all instructions that perform data casts.
Type * getSrcTy() const
Return the source type, as a convenience.
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
static LLVM_ABI unsigned isEliminableCastPair(Instruction::CastOps firstOpcode, Instruction::CastOps secondOpcode, Type *SrcTy, Type *MidTy, Type *DstTy, const DataLayout *DL)
Determine how a pair of casts can be eliminated, if they can be at all.
static LLVM_ABI CastInst * CreateIntegerCast(Value *S, Type *Ty, bool isSigned, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a ZExt, BitCast, or Trunc for int -> int casts.
static LLVM_ABI CastInst * CreateFPCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create an FPExt, BitCast, or FPTrunc for fp -> fp casts.
static LLVM_ABI CastInst * CreateTruncOrBitCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a Trunc or BitCast cast instruction.
static LLVM_ABI CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
Type * getDestTy() const
Return the destination type, as a convenience.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_UGE
unsigned greater or equal
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
static LLVM_ABI Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI bool isElementWiseEqual(Value *Y) const
Return true if this constant and a constant 'Y' are element-wise equal.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
This class represents an extension of floating point types.
This class represents a cast from floating point to signed integer.
This class represents a cast from floating point to unsigned integer.
This class represents a truncation of floating point types.
Convenience struct for specifying and reasoning about fast-math flags.
Class to represent fixed width SIMD vectors.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This instruction compares its operands according to the predicate given to the constructor.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Instruction * visitZExt(ZExtInst &Zext)
Definition InstCombineCasts.cpp:1446
Instruction * visitAddrSpaceCast(AddrSpaceCastInst &CI)
Definition InstCombineCasts.cpp:3233
Instruction * visitSExt(SExtInst &Sext)
Definition InstCombineCasts.cpp:1742
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Instruction * visitFPToSI(FPToSIInst &FI)
Definition InstCombineCasts.cpp:2315
Instruction * visitTrunc(TruncInst &CI)
Definition InstCombineCasts.cpp:970
Instruction * visitUIToFP(CastInst &CI)
Definition InstCombineCasts.cpp:2325
Instruction * visitPtrToInt(PtrToIntInst &CI)
Definition InstCombineCasts.cpp:2423
Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false, bool SimplifyBothArms=false)
Given an instruction with a select as one operand and a constant as the other operand,...
Instruction * visitSIToFP(CastInst &CI)
Definition InstCombineCasts.cpp:2335
Instruction * commonCastTransforms(CastInst &CI)
Implement the transforms common to all CastInst visitors.
Definition InstCombineCasts.cpp:190
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * foldItoFPtoI(CastInst &FI)
fpto{s/u}i({u/s}itofp(X)) --> X or zext(X) or sext(X) or trunc(X) This is safe if the intermediate ty...
Definition InstCombineCasts.cpp:2253
Instruction * visitFPTrunc(FPTruncInst &CI)
Definition InstCombineCasts.cpp:2047
Value * foldPtrToIntOrAddrOfGEP(Type *IntTy, Value *Ptr)
Definition InstCombineCasts.cpp:2387
Instruction * visitBitCast(BitCastInst &CI)
Definition InstCombineCasts.cpp:3086
Instruction * visitIntToPtr(IntToPtrInst &CI)
Definition InstCombineCasts.cpp:2347
Instruction * visitFPToUI(FPToUIInst &FI)
Definition InstCombineCasts.cpp:2305
Instruction * visitPtrToAddr(PtrToAddrInst &CI)
Definition InstCombineCasts.cpp:2466
Value * EvaluateInDifferentType(Value *V, Type *Ty, bool isSigned)
Given an expression that CanEvaluateTruncated or CanEvaluateSExtd returns true for,...
Definition InstCombineCasts.cpp:158
bool SimplifyDemandedInstructionBits(Instruction &Inst)
Tries to simplify operands to an integer instruction based on its demanded bits.
Instruction * visitFPExt(CastInst &CI)
Definition InstCombineCasts.cpp:2235
LoadInst * combineLoadToNewType(LoadInst &LI, Type *NewTy, const Twine &Suffix="")
Helper to combine a load to a new type.
The core instruction combiner logic.
const DataLayout & getDataLayout() const
unsigned ComputeMaxSignificantBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
unsigned ComputeNumSignBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
Instruction * InsertNewInstWith(Instruction *New, BasicBlock::iterator Old)
Same as InsertNewInstBefore, but also sets the debug loc.
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const Instruction *CxtI=nullptr, unsigned Depth=0) const
const SimplifyQuery & getSimplifyQuery() const
LLVM_ABI void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
static bool isBitwiseLogicOp(unsigned Opcode)
Determine if the Opcode is and/or/xor.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI void setNonNeg(bool b=true)
Set or clear the nneg flag on this instruction, which must be a zext instruction.
LLVM_ABI bool hasNonNeg() const LLVM_READONLY
Determine whether the the nneg flag is set.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
This class represents a cast from an integer to a pointer.
unsigned getAddressSpace() const
Returns the address space of this instruction's pointer type.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This class represents a cast from a pointer to an address (non-capturing ptrtoint).
Value * getPointerOperand()
Gets the pointer operand.
This class represents a cast from a pointer to an integer.
Value * getPointerOperand()
Gets the pointer operand.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class represents a truncation of integer types.
void setHasNoSignedWrap(bool B)
void setHasNoUnsignedWrap(bool B)
bool hasNoSignedWrap() const
Test whether this operation is known to never undergo signed overflow, aka the nsw property.
bool hasNoUnsignedWrap() const
Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI Type * getWithNewType(Type *EltTy) const
Given vector type, change the element type, whilst keeping the old number of elements.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isX86_AMXTy() const
Return true if this is X86 AMX.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
LLVM_ABI int getFPMantissaWidth() const
Return the width of the mantissa of this type.
LLVM_ABI const fltSemantics & getFltSemantics() const
static LLVM_ABI Type * getBFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
'undef' values are things that do not have specified contents.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
static LLVM_ABI bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
This class represents zero extension of integer types.
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
PtrToIntSameSize_match< OpTy > m_PtrToIntSameSize(const DataLayout &DL, const OpTy &Op)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_IntrinsicIntrinsic::fabs(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
IntrinsicID_match m_VScale()
Matches a call to llvm.vscale().
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
CastInst_match< OpTy, FPToUIInst > m_FPToUI(const OpTy &Op)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
cst_pred_ty< is_negated_power2 > m_NegatedPower2()
Match a integer or vector negated power-of-2.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
CastInst_match< OpTy, FPToSIInst > m_FPToSI(const OpTy &Op)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
CastOperator_match< OpTy, Instruction::IntToPtr > m_IntToPtr(const OpTy &Op)
Matches IntToPtr.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Constant * ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2)
Attempt to constant fold a select instruction with the specified operands.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
unsigned Log2_64_Ceil(uint64_t Value)
Return the ceil log base 2 of the specified value, 64 if the value is zero.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
auto dyn_cast_or_null(const Y &Val)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool replaceAllDbgUsesWith(Instruction &From, Value &To, Instruction &DomPoint, DominatorTree &DT)
Point debug users of From to To or salvage them.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
LLVM_ABI Constant * ConstantFoldIntegerCast(Constant *C, Type *DestTy, bool IsSigned, const DataLayout &DL)
Constant fold a zext, sext or trunc, depending on IsSigned and whether the DestTy is wider or narrowe...
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
LLVM_ABI Constant * ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
bool isKnownNever(FPClassTest Mask) const
Return true if it's known this can never be one of the mask entries.
SimplifyQuery getWithInstruction(const Instruction *I) const