; RUN: if [ %llvmver -lt 16 ]; then %opt < %s %loadEnzyme -enzyme-preopt=false -enzyme -mem2reg -sroa -instsimplify -simplifycfg -S | FileCheck %s; fi
; RUN: %opt < %s %newLoadEnzyme -enzyme-preopt=false -passes="enzyme,function(mem2reg,sroa,instsimplify,%simplifycfg)" -S | FileCheck %s

; THIS TEST ENSURES THAT STORES TO CONSTANT MEMORY SHOULD BE CONSIDERED CONSTANT INSTRUCTIONS

define double @caller(double* %W, double* %Wp) {
entry:
  %call = call double (i8*, ...) @__enzyme_autodiff(i8* bitcast (double (double*)* @matvec to i8*), double* %W, double* %Wp)
  ret double %call
}

define double @matvec(double* %W) {
entry:
  %result = call double @subfn(double* %W, double* null)
  ret double %result
}

define double @subfn(double* %a1, double* %res) {
entry:
  %a2 = load double, double* %a1
  store double %a2, double* %res
  ret double %a2
}

declare double @__enzyme_autodiff(i8*, ...)

; CHECK: define internal void @diffematvec(double* nocapture readonly %W, double* nocapture %"W'", double %differeturn)
; CHECK-NEXT: entry:
; CHECK-NEXT:   call void @diffesubfn(double* %W, double* %"W'", double* null, double %differeturn)
; CHECK-NEXT:   ret void
; CHECK-NEXT: }

; CHECK: define internal void @diffesubfn(double* nocapture readonly %a1, double* nocapture %"a1'", double* nocapture writeonly %res, double %differeturn)
; CHECK-NEXT: entry:
; CHECK-NEXT:   %a2 = load double, double* %a1
; CHECK-NEXT:   store double %a2, double* %res
; CHECK-NEXT:   %0 = load double, double* %"a1'"
; CHECK-NEXT:   %1 = fadd fast double %0, %differeturn
; CHECK-NEXT:   store double %1, double* %"a1'"
; CHECK-NEXT:   ret void
; CHECK-NEXT: }
