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

%mat = type { float* }

define float @f(float** %this) {
entry:
  %call = tail call float* @sub(float** %this)
  %res = load float, float* %call, align 4
  ret float %res
}

define float* @sub(float** %this)  {
entry:
  %0 = load float*, float** %this, align 8
  ret float* %0
}

define float @g(float** %this, float** %dthis) {
entry:
  %0 = tail call float (float (float**)*, ...) @__enzyme_autodiff(float (float**)* @f, float** %this, float** %dthis)
  ret float %0
}

declare float @__enzyme_autodiff(float (float**)*, ...)

; CHECK: define internal void @diffef(float** nocapture readonly %this, float** nocapture %"this'", float %differeturn)
; CHECK-NEXT: entry:
; CHECK-NEXT:   %[[augsub:.+]] = call float* @augmented_sub(float** %this, float** %"this'")
; CHECK-NEXT:   %[[loadsub:.+]] = load float, float* %[[augsub]]
; CHECK-NEXT:   %[[fadd:.+]] = fadd fast float %[[loadsub]], %differeturn
; CHECK-NEXT:   store float %[[fadd]], float* %[[augsub]]
; CHECK-NEXT:   call void @diffesub(float** %this, float** {{(undef|poison)}})
; CHECK-NEXT:   ret void
; CHECK-NEXT: }

; CHECK: define internal float* @augmented_sub(float** nocapture readonly %this, float** nocapture %"this'")
; CHECK-NEXT: entry:
; CHECK-NEXT:   %"'ipl" = load float*, float** %"this'", align 8
; CHECK-NEXT:   ret float* %"'ipl"
; CHECK-NEXT: }

; CHECK: define internal void @diffesub(float** nocapture readonly %this, float** nocapture %"this'")
; CHECK-NEXT: entry:
; CHECK-NEXT:   ret void
; CHECK-NEXT: }
