Bug type: crash
Component: LoopVectorize
Bug location: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp: VPlanTransforms::truncateToMinimalBitwidths
Issue title: Assertion `MinBWs.size() == NumProcessedRecipes && "some entries in MinBWs haven't been processed"' failed. for opt -passes=loop-vectorize
Labels: vectorizers
crash
Reported by: mikaelholmen

llvm commit: c1ed45a271145
Reproduce with: ```opt -passes="loop-vectorize" bbi-90681_2.ll -S -o /dev/null -mtriple=x86_64```
Result:
```
opt: ../lib/Transforms/Vectorize/VPlanTransforms.cpp:997: static void llvm::VPlanTransforms::truncateToMinimalBitwidths(llvm::VPlan &, const MapVector<llvm::Instruction *, uint64_t> &, llvm::LLVMContext &): Assertion `MinBWs.size() == NumProcessedRecipes && "some entries in MinBWs haven't been processed"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: ../../main-github/llvm/build-all/bin/opt -passes=loop-vectorize bbi-90681_2.ll -S -o /dev/null -mtriple=x86_64
 #0 0x0000563bdd2b15d7 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (../../main-github/llvm/build-all/bin/opt+0x63c95d7)
 #1 0x0000563bdd2af12e llvm::sys::RunSignalHandlers() (../../main-github/llvm/build-all/bin/opt+0x63c712e)
 #2 0x0000563bdd2b1c9f SignalHandler(int) (../../main-github/llvm/build-all/bin/opt+0x63c9c9f)
 #3 0x00007f87a7de7630 __restore_rt (/lib64/libpthread.so.0+0xf630)
 #4 0x00007f87a552e387 raise (/lib64/libc.so.6+0x36387)
 #5 0x00007f87a552fa78 abort (/lib64/libc.so.6+0x37a78)
 #6 0x00007f87a55271a6 __assert_fail_base (/lib64/libc.so.6+0x2f1a6)
 #7 0x00007f87a5527252 (/lib64/libc.so.6+0x2f252)
 #8 0x0000563bdd584d86 (../../main-github/llvm/build-all/bin/opt+0x669cd86)
 #9 0x0000563bdd50f875 llvm::LoopVectorizationPlanner::buildVPlansWithVPRecipes(llvm::ElementCount, llvm::ElementCount) (../../main-github/llvm/build-all/bin/opt+0x6627875)
#10 0x0000563bdd50eeec llvm::LoopVectorizationPlanner::plan(llvm::ElementCount, unsigned int) (../../main-github/llvm/build-all/bin/opt+0x6626eec)
#11 0x0000563bdd522bc9 llvm::LoopVectorizePass::processLoop(llvm::Loop*) (../../main-github/llvm/build-all/bin/opt+0x663abc9)
#12 0x0000563bdd5289b3 llvm::LoopVectorizePass::runImpl(llvm::Function&, llvm::ScalarEvolution&, llvm::LoopInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::BlockFrequencyInfo*, llvm::TargetLibraryInfo*, llvm::DemandedBits&, llvm::AssumptionCache&, llvm::LoopAccessInfoManager&, llvm::OptimizationRemarkEmitter&, llvm::ProfileSummaryInfo*) (../../main-github/llvm/build-all/bin/opt+0x66409b3)
#13 0x0000563bdd529318 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (../../main-github/llvm/build-all/bin/opt+0x6641318)
#14 0x0000563bdd4cafad llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (../../main-github/llvm/build-all/bin/opt+0x65e2fad)
#15 0x0000563bdcce36d4 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (../../main-github/llvm/build-all/bin/opt+0x5dfb6d4)
#16 0x0000563bdb09c87d llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function> >, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (../../main-github/llvm/build-all/bin/opt+0x41b487d)
#17 0x0000563bdcce7abe llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (../../main-github/llvm/build-all/bin/opt+0x5dffabe)
#18 0x0000563bdb09c61d llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (../../main-github/llvm/build-all/bin/opt+0x41b461d)
#19 0x0000563bdcce27f6 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (../../main-github/llvm/build-all/bin/opt+0x5dfa7f6)
#20 0x0000563bdabb7143 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool) (../../main-github/llvm/build-all/bin/opt+0x3ccf143)
#21 0x0000563bdabc5844 main (../../main-github/llvm/build-all/bin/opt+0x3cdd844)
#22 0x00007f87a551a555 __libc_start_main (/lib64/libc.so.6+0x22555)
#23 0x0000563bdabb12e9 _start (../../main-github/llvm/build-all/bin/opt+0x3cc92e9)
Abort (core dumped)
```
[bbi-90681_2.ll.gz](https://github.com/llvm/llvm-project/files/13874170/bbi-90681_2.ll.gz)


Comments: author: mikaelholmen
body: This starts happening with 70535f5e609f747c28
```
[VPlan] Replace IR based truncateToMinimalBitwidths with VPlan version.
```
Ping @fhahn 

author: mikaelholmen
body: Thanks!

Fix patch:
commit 59d6f033a25d161e494457e8bb6e30375eb7f40f
Author: Florian Hahn <flo@fhahn.com>
Date:   Fri Jan 12 13:14:13 2024 +0000

    [VPlan] Support narrowing widened loads in truncateToMinimimalBitwidths.
    
    MinBWs may also contain widened load instructions, handle them by only
    narrowing their result.
    
    Fixes https://github.com/llvm/llvm-project/issues/77468

diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 5c430620a2dc..b3694e74a385 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -895,7 +895,10 @@ void VPlanTransforms::truncateToMinimalBitwidths(
            vp_depth_first_deep(Plan.getVectorLoopRegion()))) {
     for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
       if (!isa<VPWidenRecipe, VPWidenCastRecipe, VPReplicateRecipe,
-               VPWidenSelectRecipe>(&R))
+               VPWidenSelectRecipe, VPWidenMemoryInstructionRecipe>(&R))
+        continue;
+      if (isa<VPWidenMemoryInstructionRecipe>(&R) &&
+          cast<VPWidenMemoryInstructionRecipe>(&R)->isStore())
         continue;
 
       VPValue *ResultVPV = R.getVPSingleValue();
@@ -948,6 +951,23 @@ void VPlanTransforms::truncateToMinimalBitwidths(
 
       auto *NewResTy = IntegerType::get(Ctx, NewResSizeInBits);
 
+      // Any wrapping introduced by shrinking this operation shouldn't be
+      // considered undefined behavior. So, we can't unconditionally copy
+      // arithmetic wrapping flags to VPW.
+      if (auto *VPW = dyn_cast<VPRecipeWithIRFlags>(&R))
+        VPW->dropPoisonGeneratingFlags();
+
+      // Extend result to original width.
+      auto *Ext = new VPWidenCastRecipe(Instruction::ZExt, ResultVPV, OldResTy);
+      Ext->insertAfter(&R);
+      ResultVPV->replaceAllUsesWith(Ext);
+      Ext->setOperand(0, ResultVPV);
+
+      if (isa<VPWidenMemoryInstructionRecipe>(&R)) {
+        assert(!cast<VPWidenMemoryInstructionRecipe>(&R)->isStore() && "stores cannot be narrowed");
+        continue;
+      }
+
       // Shrink operands by introducing truncates as needed.
       unsigned StartIdx = isa<VPWidenSelectRecipe>(&R) ? 1 : 0;
       for (unsigned Idx = StartIdx; Idx != R.getNumOperands(); ++Idx) {
@@ -979,17 +999,6 @@ void VPlanTransforms::truncateToMinimalBitwidths(
         }
       }
 
-      // Any wrapping introduced by shrinking this operation shouldn't be
-      // considered undefined behavior. So, we can't unconditionally copy
-      // arithmetic wrapping flags to VPW.
-      if (auto *VPW = dyn_cast<VPRecipeWithIRFlags>(&R))
-        VPW->dropPoisonGeneratingFlags();
-
-      // Extend result to original width.
-      auto *Ext = new VPWidenCastRecipe(Instruction::ZExt, ResultVPV, OldResTy);
-      Ext->insertAfter(&R);
-      ResultVPV->replaceAllUsesWith(Ext);
-      Ext->setOperand(0, ResultVPV);
     }
   }
 


Regression tests:
file: llvm/test/Transforms/LoopVectorize/trunc-loads-p16.ll
commands: opt -p loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S %s
tests: test_name: pr77468
test_body: target datalayout = "p:16:16"

define void @pr77468(ptr noalias %src, ptr noalias %dst, i1 %x) {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i16 [ 0, %entry ], [ %iv.next, %loop ]
  %gep.src = getelementptr i32, ptr %src, i16 %iv
  %l = load i32, ptr %gep.src, align 1
  %x.ext = zext i1 %x to i32
  %and = and i32 %x.ext, %l
  %gep.dst = getelementptr i16, ptr %dst, i16 %iv
  %t = trunc i32 %and to i16
  store i16 %t, ptr %gep.dst, align 2
  %iv.next = add i16 %iv, 1
  %exitcond.not = icmp eq i16 %iv.next, 100
  br i1 %exitcond.not, label %exit, label %loop

exit:                                             ; preds = %loop
  ret void
}