Bug type: crash
Component: LoopVectorize
Bug location: llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h: getVPValueOrAddLiveIn
Issue title: [clang] Assertion failed in Vectorize
Labels: vectorizers
confirmed
crash
Reported by: cardigan1008

To reproduce, compile it with -O2: clang -O2 example.c

```c
#include <stdint.h>
int a;
long b;
static int32_t c;
void d(int e, int h) {
  int f = a = 1;
  for (; a <= e; a++)
    f *= a;
  a = 0;
  for (; a < h; a++)
    b *= f;
}
long g() {}
int32_t i() {
  for (; g();)
    for (c = 3;;)
      ;
}
uint16_t j() { d(c + 1, c + 6); }
```

The error message is as follows:

```
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:9985: bool llvm::LoopVectorizePass::processLoop(llvm::Loop *): Assertion `VF.Width == BestVF && "VPlan cost model and legacy cost model disagreed"' failed.
```

Comments: author: EugeneZelenko
body: See https://godbolt.org/z/jc8qqo8Ta
author: shafik
body: Looks like a recent regression since it does not crash on trunk: https://godbolt.org/z/sKjdvMq54

Assertion:

```console
clang++: /root/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:7288: 
llvm::VectorizationFactor llvm::LoopVectorizationPlanner::computeBestVF():
Assertion `BestFactor.Width == LegacyVF.Width && " VPlan cost model and legacy cost model disagreed"' failed.
```

Backtrace: 

```console
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -gdwarf-4 -g -o /app/output.s -mllvm --x86-asm-syntax=intel -fno-verbose-asm -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -x c -O2 <source>
1.	<eof> parser at end of file
2.	Optimizer
3.	Running pass "function<eager-inv>(float2int,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-unroll<O2>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch;speculate-unpredictables>)" on module "<source>"
4.	Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "j"
 #0 0x0000000003b02648 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3b02648)
 #1 0x0000000003b0033c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3b0033c)
 #2 0x0000000003a492b8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x000078485ee42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x000078485ee969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #5 0x000078485ee42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #6 0x000078485ee287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #7 0x000078485ee2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #8 0x000078485ee39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #9 0x00000000054df418 llvm::LoopVectorizationPlanner::computeBestVF() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x54df418)
#10 0x00000000054fa07a llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x54fa07a)
#11 0x00000000054fcd39 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x54fcd39)
#12 0x00000000054fd3c3 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x54fd3c3)
#13 0x00000000050ac09e llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x50ac09e)
#14 0x00000000034cac68 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x34cac68)
#15 0x00000000010bce6e llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x10bce6e)
#16 0x00000000034c966e llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x34c966e)
#17 0x00000000010bc75e llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x10bc75e)
#18 0x00000000034c7800 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x34c7800)
#19 0x0000000003da8895 (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>&, std::unique_ptr<llvm::ToolOutputFile, std::default_delete<llvm::ToolOutputFile>>&, clang::BackendConsumer*) BackendUtil.cpp:0:0
#20 0x0000000003dab9fd clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3dab9fd)
#21 0x00000000044196ac clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44196ac)
#22 0x000000000651f80c clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x651f80c)
#23 0x0000000004419b18 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4419b18)
#24 0x00000000046a79f9 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x46a79f9)
#25 0x000000000462b30e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x462b30e)
#26 0x000000000479104e clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x479104e)
#27 0x0000000000ca5b0f cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xca5b0f)
#28 0x0000000000c9ed5a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#29 0x000000000445d1d9 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#30 0x0000000003a49764 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3a49764)
#31 0x000000000445d7cf clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#32 0x0000000004423365 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4423365)
#33 0x0000000004423dcd clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4423dcd)
#34 0x000000000442b9e5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x442b9e5)
#35 0x0000000000ca2f05 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xca2f05)
#36 0x0000000000b776e4 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xb776e4)
#37 0x000078485ee29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#38 0x000078485ee29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#39 0x0000000000c9e80e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc9e80e)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134
```
author: cardigan1008
body: The crash persists in the above cases even with the applied patches. 
author: fhahn
body: @cardigan1008 I can't reproduce the crash locally with latest main. If it still reproduces on current main for you, could you share the crashing IR, using `-mllvm -print-on-crash -mllvm -print-module-scope`?
author: cardigan1008
body: @fhahn Apologies for the confusion. I pulled the latest version, and this case is now working. However, I encountered a similar crash with another case that I'm currently fuzzing. I'll open a separate issue as soon as I've finished reducing it.
author: cardigan1008
body: Hi @fhahn , I have submitted another issue with the same crash in #106248 . 

Fix patch:
commit 533e6bbd0d344a710c491a9eb0ce0ba0852b08cb
Author: Florian Hahn <flo@fhahn.com>
Date:   Mon Aug 26 09:15:58 2024 +0100

    [VPlan] Simplify live-ins if they are SCEVConstant.
    
    The legacy cost model in some parts checks if any of the operands are
    constants via SCEV. Update VPlan construction to replace live-ins that
    are constants via SCEV with such constants. This means VPlans (and
    codegen) reflects what we computing the cost of and removes another case
    where the legacy and VPlan cost model diverged.
    
    Fixes https://github.com/llvm/llvm-project/issues/105722.

diff --git a/llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h b/llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h
index 0b27933925d8..0fbdeeddaf4a 100644
--- a/llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h
+++ b/llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h
@@ -13,6 +13,7 @@
 #include "VPlan.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
 #include "llvm/IR/IRBuilder.h"
 
 namespace llvm {
@@ -173,6 +174,11 @@ public:
       if (auto *R = Ingredient2Recipe.lookup(I))
         return R->getVPSingleValue();
     }
+    ScalarEvolution &SE = *PSE.getSE();
+    if (!isa<Constant>(V) && SE.isSCEVable(V->getType()))
+      if (auto *C = dyn_cast<SCEVConstant>(PSE.getSE()->getSCEV(V)))
+        return Plan.getOrAddLiveIn(C->getValue());
+
     return Plan.getOrAddLiveIn(V);
   }
 };


Regression tests:
file: llvm/test/Transforms/LoopVectorize/X86/cost-model.ll
commands: opt < %s -passes=loop-vectorize -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx -S
tests: test_name: cost_assume
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

define i64 @cost_assume(ptr %end, i64 %N) {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %0 = phi i64 [ 0, %entry ], [ %1, %loop ]
  %1 = add i64 %0, 1
  %iv.next = add nsw i64 %iv, 1
  %c = icmp ne i64 %N, 0
  tail call void @llvm.assume(i1 %c)
  %gep = getelementptr nusw [9 x i8], ptr null, i64 %iv.next
  %ec = icmp eq ptr %gep, %end
  br i1 %ec, label %exit, label %loop

exit:                                             ; preds = %loop
  ret i64 %1
}

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write)
declare void @llvm.assume(i1 noundef) #0

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }

test_name: cost_model_1
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

@c = external global [2048 x i32], align 16
@b = external global [2048 x i32], align 16
@d = external global [2048 x i32], align 16
@a = external global [2048 x i32], align 16

; Function Attrs: noinline nounwind ssp uwtable
define void @cost_model_1() #0 {
entry:
  br label %for.body

for.body:                                         ; preds = %for.body, %entry
  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  %0 = shl nsw i64 %indvars.iv, 1
  %arrayidx = getelementptr inbounds [2048 x i32], ptr @c, i64 0, i64 %0
  %1 = load i32, ptr %arrayidx, align 8
  %idxprom1 = sext i32 %1 to i64
  %arrayidx2 = getelementptr inbounds [2048 x i32], ptr @b, i64 0, i64 %idxprom1
  %2 = load i32, ptr %arrayidx2, align 4
  %arrayidx4 = getelementptr inbounds [2048 x i32], ptr @d, i64 0, i64 %indvars.iv
  %3 = load i32, ptr %arrayidx4, align 4
  %idxprom5 = sext i32 %3 to i64
  %arrayidx6 = getelementptr inbounds [2048 x i32], ptr @a, i64 0, i64 %idxprom5
  store i32 %2, ptr %arrayidx6, align 4
  %indvars.iv.next = add i64 %indvars.iv, 1
  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  %exitcond = icmp eq i32 %lftr.wideiv, 256
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %for.body
  ret void
}

attributes #0 = { noinline nounwind ssp uwtable }

test_name: avx512_cond_load_cost
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

define i64 @avx512_cond_load_cost(ptr %src, i32 %a, i64 %b, i32 %c, i32 %d) #0 {
entry:
  br label %loop.header

loop.header:                                      ; preds = %loop.latch, %entry
  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
  %c.1 = icmp slt i32 %iv, 0
  br i1 %c.1, label %if.then, label %loop.latch

if.then:                                          ; preds = %loop.header
  %0 = urem i32 %a, %c
  %mul = sub i32 0, %0
  %div = udiv i32 %c, %d
  %or = or i32 %div, %mul
  %ext = sext i32 %or to i64
  %gep = getelementptr { i64, i64, i64 }, ptr %src, i64 %ext, i32 2
  %l = load i64, ptr %gep, align 8
  %or.2 = or i64 %l, %b
  br label %loop.latch

loop.latch:                                       ; preds = %if.then, %loop.header
  %res = phi i64 [ 0, %loop.header ], [ %or.2, %if.then ]
  %iv.next = add i32 %iv, 1
  %ec = icmp ult i32 %iv, %c
  br i1 %ec, label %loop.header, label %exit

exit:                                             ; preds = %loop.latch
  ret i64 %res
}

attributes #0 = { "target-features"="+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl" }

test_name: multi_exit
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

define void @multi_exit(ptr %dst, ptr %src.1, ptr %src.2, i64 %A, i64 %B) #0 {
entry:
  br label %loop

loop:                                             ; preds = %loop.latch, %entry
  %iv.1.wide = phi i64 [ 0, %entry ], [ %iv.1.next.wide, %loop.latch ]
  %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop.latch ]
  %ec.1 = icmp ult i64 %iv.1.wide, %A
  br i1 %ec.1, label %loop.latch, label %exit

loop.latch:                                       ; preds = %loop
  %l.1 = load i64, ptr %src.1, align 8
  %l.2 = load i64, ptr %src.2, align 8
  %cmp55.us = icmp eq i64 %l.1, 0
  %cmp.i.us = icmp ne i64 %l.2, 0
  %and = and i1 %cmp.i.us, %cmp55.us
  %ext = zext i1 %and to i8
  store i8 %ext, ptr %dst, align 1
  %iv.1.next = add i32 %iv.1, 1
  %iv.1.next.wide = zext i32 %iv.1.next to i64
  %ec.2 = icmp ult i64 %iv.1.next.wide, %B
  br i1 %ec.2, label %loop, label %exit

exit:                                             ; preds = %loop.latch, %loop
  ret void
}

attributes #0 = { "target-cpu"="penryn" }

test_name: cost_duplicate_recipe_for_sinking
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

define void @cost_duplicate_recipe_for_sinking(ptr %A, i64 %N) #0 {
entry:
  br label %loop.header

loop.header:                                      ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
  %iv.shl = shl nsw i64 %iv, 2
  %gep.0 = getelementptr nusw double, ptr %A, i64 %iv.shl
  %l = load double, ptr %gep.0, align 8
  %c = fcmp oeq double %l, 0.000000e+00
  br i1 %c, label %if.then, label %loop.latch

if.then:                                          ; preds = %loop.header
  %gep.1 = getelementptr double, ptr %A, i64 %iv.shl
  store double 0.000000e+00, ptr %gep.1, align 8
  br label %loop.latch

loop.latch:                                       ; preds = %if.then, %loop.header
  %iv.next = add nsw i64 %iv, 1
  %ec = icmp eq i64 %iv, %N
  br i1 %ec, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret void
}

attributes #0 = { "target-cpu"="znver3" }

test_name: any_of_cost
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

define i1 @any_of_cost(ptr %start, ptr %end) #0 {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %any.of = phi i1 [ false, %entry ], [ %any.of.next, %loop ]
  %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop ]
  %gep = getelementptr i8, ptr %ptr.iv, i64 8
  %l = load ptr, ptr %gep, align 8
  %cmp13.not.not = icmp eq ptr %l, null
  %any.of.next = select i1 %cmp13.not.not, i1 %any.of, i1 false
  %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 40
  %cmp.not = icmp eq ptr %ptr.iv, %end
  br i1 %cmp.not, label %exit, label %loop

exit:                                             ; preds = %loop
  ret i1 %any.of.next
}

attributes #0 = { "target-cpu"="penryn" }

test_name: live_in_known_1_via_scev
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

define i64 @live_in_known_1_via_scev() {
entry:
  %sel = select i1 false, i32 3, i32 0
  br label %ph

ph:                                               ; preds = %entry
  %p = phi i32 [ 1, %entry ]
  %N = add nuw nsw i32 %sel, 6
  %p.ext = zext nneg i32 %p to i64
  br label %loop

loop:                                             ; preds = %loop, %ph
  %iv = phi i32 [ 0, %ph ], [ %iv.next, %loop ]
  %red = phi i64 [ 3, %ph ], [ %red.mul, %loop ]
  %red.mul = mul nsw i64 %red, %p.ext
  %iv.next = add nuw nsw i32 %iv, 1
  %ec = icmp eq i32 %iv.next, %N
  br i1 %ec, label %exit, label %loop

exit:                                             ; preds = %loop
  %res = phi i64 [ %red.mul, %loop ]
  ret i64 %res
}

test_name: reduction_store
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

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

loop:                                             ; preds = %loop, %entry
  %red = phi i32 [ 0, %entry ], [ %red.next, %loop ]
  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
  %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv
  %l = load i32, ptr %gep.src, align 4
  %l.and = and i32 %l, 3
  store i32 %l.and, ptr %dst, align 4
  %x.ext = zext i1 %x to i64
  %lshr = lshr i64 %x.ext, 12
  %t = trunc i64 %lshr to i32
  %red.next = and i32 %red, %t
  store i32 %red.next, ptr %dst, align 4
  %iv.next = add i32 %iv, 1
  %ec = icmp eq i32 %iv, 29
  br i1 %ec, label %exit, label %loop

exit:                                             ; preds = %loop
  ret void
}

attributes #0 = { "target-cpu"="znver3" }

test_name: PR27826
test_body: target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

define float @PR27826(ptr nocapture readonly %a, ptr nocapture readonly %b, i32 %n) {
entry:
  %cmp = icmp sgt i32 %n, 0
  br i1 %cmp, label %preheader, label %for.end

preheader:                                        ; preds = %entry
  %t0 = sext i32 %n to i64
  br label %for

for:                                              ; preds = %for, %preheader
  %indvars.iv = phi i64 [ 0, %preheader ], [ %indvars.iv.next, %for ]
  %s.02 = phi float [ 0.000000e+00, %preheader ], [ %add4, %for ]
  %arrayidx = getelementptr inbounds float, ptr %a, i64 %indvars.iv
  %t1 = load float, ptr %arrayidx, align 4
  %arrayidx3 = getelementptr inbounds float, ptr %b, i64 %indvars.iv
  %t2 = load float, ptr %arrayidx3, align 4
  %add = fadd fast float %t1, %s.02
  %add4 = fadd fast float %add, %t2
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 32
  %cmp1 = icmp slt i64 %indvars.iv.next, %t0
  br i1 %cmp1, label %for, label %loopexit

loopexit:                                         ; preds = %for
  %add4.lcssa = phi float [ %add4, %for ]
  br label %for.end

for.end:                                          ; preds = %loopexit, %entry
  %s.0.lcssa = phi float [ 0.000000e+00, %entry ], [ %add4.lcssa, %loopexit ]
  ret float %s.0.lcssa
}