@@ -3698,7 +3698,7 @@ bool VectorCombine::foldInterleaveIntrinsics(Instruction &I) {
3698
3698
bool VectorCombine::shrinkLoadForShuffles (Instruction &I) {
3699
3699
auto *InputShuffle = dyn_cast<ShuffleVectorInst>(&I);
3700
3700
if (!InputShuffle)
3701
- return {} ;
3701
+ return false ;
3702
3702
3703
3703
auto *OldLoad = dyn_cast<LoadInst>(InputShuffle->getOperand (0u ));
3704
3704
if (!OldLoad || !OldLoad->isSimple ())
@@ -3708,34 +3708,31 @@ bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
3708
3708
if (!VecTy)
3709
3709
return false ;
3710
3710
3711
- auto IsPoisonOrUndef = [](Value *V) -> bool {
3712
- if (auto *C = dyn_cast<Constant>(V)) {
3713
- return isa<PoisonValue>(C) || isa<UndefValue>(C);
3714
- }
3715
- return false ;
3716
- };
3717
-
3711
+ // Search all uses of `I`. If all uses are shufflevector ops, and the second
3712
+ // operands are all poison values, find the minimum and maximum indices of
3713
+ // the vector elements referenced by all shuffle masks.
3714
+ // Otherwise return `std::nullopt`.
3718
3715
using IndexRange = std::pair<int , int >;
3719
3716
auto GetIndexRangeInShuffles = [&]() -> std::optional<IndexRange> {
3720
- auto OutputRange = IndexRange (VecTy->getNumElements (), -1 );
3717
+ IndexRange OutputRange = IndexRange (VecTy->getNumElements (), -1 );
3721
3718
for (auto &Use : I.uses ()) {
3722
3719
// All uses must be ShuffleVector instructions.
3723
3720
auto *Shuffle = dyn_cast<ShuffleVectorInst>(Use.getUser ());
3724
3721
if (!Shuffle)
3725
- return {} ;
3722
+ return std::nullopt ;
3726
3723
3727
3724
// Get index range for value.
3728
- auto *Op0 = Shuffle->getOperand (0u );
3729
- auto *Op1 = Shuffle->getOperand (1u );
3730
- if (!IsPoisonOrUndef (Op1))
3731
- return {} ;
3725
+ auto *Op0 = Shuffle->getOperand (0 );
3726
+ auto *Op1 = Shuffle->getOperand (1 );
3727
+ if (!isa<PoisonValue>(Op1) && !isa<UndefValue> (Op1))
3728
+ return std::nullopt ;
3732
3729
3733
3730
// Find the min and max indices used by the ShuffleVector instruction.
3734
- auto Mask = Shuffle->getShuffleMask ();
3731
+ ArrayRef< int > Mask = Shuffle->getShuffleMask ();
3735
3732
auto *Op0Ty = cast<FixedVectorType>(Op0->getType ());
3736
3733
auto NumElems = int (Op0Ty->getNumElements ());
3737
3734
3738
- for (auto Index : Mask) {
3735
+ for (int Index : Mask) {
3739
3736
if (Index >= 0 ) {
3740
3737
Index %= NumElems;
3741
3738
OutputRange.first = std::min (Index, OutputRange.first );
@@ -3745,15 +3742,18 @@ bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
3745
3742
}
3746
3743
3747
3744
if (OutputRange.second < OutputRange.first )
3748
- return {} ;
3745
+ return std::nullopt ;
3749
3746
3750
3747
return OutputRange;
3751
3748
};
3752
3749
3750
+ // Find the range of vector elements used by shufflevector ops, if possible.
3753
3751
if (auto Indices = GetIndexRangeInShuffles ()) {
3754
- auto OldSize = VecTy->getNumElements ();
3755
- auto NewSize = Indices->second + 1u ;
3752
+ unsigned OldSize = VecTy->getNumElements ();
3753
+ unsigned NewSize = Indices->second + 1u ;
3756
3754
3755
+ // If the range of vector elements is smaller than the full load, attempt
3756
+ // to create a smaller load.
3757
3757
if (NewSize < OldSize) {
3758
3758
auto Builder = IRBuilder (&I);
3759
3759
Builder.SetCurrentDebugLocation (I.getDebugLoc ());
0 commit comments