@@ -3405,7 +3405,7 @@ bool VectorCombine::foldInterleaveIntrinsics(Instruction &I) {
3405
3405
bool VectorCombine::shrinkLoadForShuffles (Instruction &I) {
3406
3406
auto *InputShuffle = dyn_cast<ShuffleVectorInst>(&I);
3407
3407
if (!InputShuffle)
3408
- return {} ;
3408
+ return false ;
3409
3409
3410
3410
auto *OldLoad = dyn_cast<LoadInst>(InputShuffle->getOperand (0u ));
3411
3411
if (!OldLoad || !OldLoad->isSimple ())
@@ -3415,34 +3415,31 @@ bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
3415
3415
if (!VecTy)
3416
3416
return false ;
3417
3417
3418
- auto IsPoisonOrUndef = [](Value *V) -> bool {
3419
- if (auto *C = dyn_cast<Constant>(V)) {
3420
- return isa<PoisonValue>(C) || isa<UndefValue>(C);
3421
- }
3422
- return false ;
3423
- };
3424
-
3418
+ // Search all uses of `I`. If all uses are shufflevector ops, and the second
3419
+ // operands are all poison values, find the minimum and maximum indices of
3420
+ // the vector elements referenced by all shuffle masks.
3421
+ // Otherwise return `std::nullopt`.
3425
3422
using IndexRange = std::pair<int , int >;
3426
3423
auto GetIndexRangeInShuffles = [&]() -> std::optional<IndexRange> {
3427
- auto OutputRange = IndexRange (VecTy->getNumElements (), -1 );
3424
+ IndexRange OutputRange = IndexRange (VecTy->getNumElements (), -1 );
3428
3425
for (auto &Use : I.uses ()) {
3429
3426
// All uses must be ShuffleVector instructions.
3430
3427
auto *Shuffle = dyn_cast<ShuffleVectorInst>(Use.getUser ());
3431
3428
if (!Shuffle)
3432
- return {} ;
3429
+ return std::nullopt ;
3433
3430
3434
3431
// Get index range for value.
3435
- auto *Op0 = Shuffle->getOperand (0u );
3436
- auto *Op1 = Shuffle->getOperand (1u );
3437
- if (!IsPoisonOrUndef (Op1))
3438
- return {} ;
3432
+ auto *Op0 = Shuffle->getOperand (0 );
3433
+ auto *Op1 = Shuffle->getOperand (1 );
3434
+ if (!isa<PoisonValue>(Op1) && !isa<UndefValue> (Op1))
3435
+ return std::nullopt ;
3439
3436
3440
3437
// Find the min and max indices used by the ShuffleVector instruction.
3441
- auto Mask = Shuffle->getShuffleMask ();
3438
+ ArrayRef< int > Mask = Shuffle->getShuffleMask ();
3442
3439
auto *Op0Ty = cast<FixedVectorType>(Op0->getType ());
3443
3440
auto NumElems = int (Op0Ty->getNumElements ());
3444
3441
3445
- for (auto Index : Mask) {
3442
+ for (int Index : Mask) {
3446
3443
if (Index >= 0 ) {
3447
3444
Index %= NumElems;
3448
3445
OutputRange.first = std::min (Index, OutputRange.first );
@@ -3452,15 +3449,18 @@ bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
3452
3449
}
3453
3450
3454
3451
if (OutputRange.second < OutputRange.first )
3455
- return {} ;
3452
+ return std::nullopt ;
3456
3453
3457
3454
return OutputRange;
3458
3455
};
3459
3456
3457
+ // Find the range of vector elements used by shufflevector ops, if possible.
3460
3458
if (auto Indices = GetIndexRangeInShuffles ()) {
3461
- auto OldSize = VecTy->getNumElements ();
3462
- auto NewSize = Indices->second + 1u ;
3459
+ unsigned OldSize = VecTy->getNumElements ();
3460
+ unsigned NewSize = Indices->second + 1u ;
3463
3461
3462
+ // If the range of vector elements is smaller than the full load, attempt
3463
+ // to create a smaller load.
3464
3464
if (NewSize < OldSize) {
3465
3465
auto Builder = IRBuilder (&I);
3466
3466
Builder.SetCurrentDebugLocation (I.getDebugLoc ());
0 commit comments