@@ -3490,7 +3490,7 @@ bool VectorCombine::foldInterleaveIntrinsics(Instruction &I) {
3490
3490
bool VectorCombine::shrinkLoadForShuffles (Instruction &I) {
3491
3491
auto *InputShuffle = dyn_cast<ShuffleVectorInst>(&I);
3492
3492
if (!InputShuffle)
3493
- return {} ;
3493
+ return false ;
3494
3494
3495
3495
auto *OldLoad = dyn_cast<LoadInst>(InputShuffle->getOperand (0u ));
3496
3496
if (!OldLoad || !OldLoad->isSimple ())
@@ -3500,34 +3500,31 @@ bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
3500
3500
if (!VecTy)
3501
3501
return false ;
3502
3502
3503
- auto IsPoisonOrUndef = [](Value *V) -> bool {
3504
- if (auto *C = dyn_cast<Constant>(V)) {
3505
- return isa<PoisonValue>(C) || isa<UndefValue>(C);
3506
- }
3507
- return false ;
3508
- };
3509
-
3503
+ // Search all uses of `I`. If all uses are shufflevector ops, and the second
3504
+ // operands are all poison values, find the minimum and maximum indices of
3505
+ // the vector elements referenced by all shuffle masks.
3506
+ // Otherwise return `std::nullopt`.
3510
3507
using IndexRange = std::pair<int , int >;
3511
3508
auto GetIndexRangeInShuffles = [&]() -> std::optional<IndexRange> {
3512
- auto OutputRange = IndexRange (VecTy->getNumElements (), -1 );
3509
+ IndexRange OutputRange = IndexRange (VecTy->getNumElements (), -1 );
3513
3510
for (auto &Use : I.uses ()) {
3514
3511
// All uses must be ShuffleVector instructions.
3515
3512
auto *Shuffle = dyn_cast<ShuffleVectorInst>(Use.getUser ());
3516
3513
if (!Shuffle)
3517
- return {} ;
3514
+ return std::nullopt ;
3518
3515
3519
3516
// Get index range for value.
3520
- auto *Op0 = Shuffle->getOperand (0u );
3521
- auto *Op1 = Shuffle->getOperand (1u );
3522
- if (!IsPoisonOrUndef (Op1))
3523
- return {} ;
3517
+ auto *Op0 = Shuffle->getOperand (0 );
3518
+ auto *Op1 = Shuffle->getOperand (1 );
3519
+ if (!isa<PoisonValue>(Op1) && !isa<UndefValue> (Op1))
3520
+ return std::nullopt ;
3524
3521
3525
3522
// Find the min and max indices used by the ShuffleVector instruction.
3526
- auto Mask = Shuffle->getShuffleMask ();
3523
+ ArrayRef< int > Mask = Shuffle->getShuffleMask ();
3527
3524
auto *Op0Ty = cast<FixedVectorType>(Op0->getType ());
3528
3525
auto NumElems = int (Op0Ty->getNumElements ());
3529
3526
3530
- for (auto Index : Mask) {
3527
+ for (int Index : Mask) {
3531
3528
if (Index >= 0 ) {
3532
3529
Index %= NumElems;
3533
3530
OutputRange.first = std::min (Index, OutputRange.first );
@@ -3537,15 +3534,18 @@ bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
3537
3534
}
3538
3535
3539
3536
if (OutputRange.second < OutputRange.first )
3540
- return {} ;
3537
+ return std::nullopt ;
3541
3538
3542
3539
return OutputRange;
3543
3540
};
3544
3541
3542
+ // Find the range of vector elements used by shufflevector ops, if possible.
3545
3543
if (auto Indices = GetIndexRangeInShuffles ()) {
3546
- auto OldSize = VecTy->getNumElements ();
3547
- auto NewSize = Indices->second + 1u ;
3544
+ unsigned OldSize = VecTy->getNumElements ();
3545
+ unsigned NewSize = Indices->second + 1u ;
3548
3546
3547
+ // If the range of vector elements is smaller than the full load, attempt
3548
+ // to create a smaller load.
3549
3549
if (NewSize < OldSize) {
3550
3550
auto Builder = IRBuilder (&I);
3551
3551
Builder.SetCurrentDebugLocation (I.getDebugLoc ());
0 commit comments