; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
; RUN: if [ %llvmver -lt 16 ]; then %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -mem2reg -instsimplify -simplifycfg -S | FileCheck %s; fi
; RUN: %opt < %s %newLoadEnzyme -passes="enzyme,function(mem2reg,instsimplify,%simplifycfg)" -enzyme-preopt=false -S | FileCheck %s

%struct.Gradients = type { double, double, double, double, double, double }

; Function Attrs: noinline nounwind readnone uwtable
define <2 x double> @tester(<2 x double> %x) {
entry:
  %cstx = bitcast <2 x double> %x to <2 x i64>
  %negx = xor <2 x i64> %cstx, <i64 -9223372036854775808, i64 0>
  %csty = bitcast <2 x i64> %negx to <2 x double>
  ret <2 x double> %csty
}

define %struct.Gradients @test_derivative(<2 x double> %x, <2 x double> %dx1, <2 x double> %dx2, <2 x double> %dx3) {
entry:
  %0 = tail call %struct.Gradients (<2 x double> (<2 x double>)*, ...) @__enzyme_fwddiff(<2 x double> (<2 x double>)* nonnull @tester, metadata !"enzyme_width", i64 3, <2 x double> %x, <2 x double> %dx1, <2 x double> %dx2, <2 x double> %dx3)
  ret %struct.Gradients %0
}

; Function Attrs: nounwind
declare %struct.Gradients @__enzyme_fwddiff(<2 x double> (<2 x double>)*, ...)


; CHECK: define {{[^@]+}}@fwddiffe3tester(<2 x double> [[X:%.*]], [3 x <2 x double>] %"x'")
; CHECK-NEXT:  entry:
; CHECK-NEXT:    %0 = extractvalue [3 x <2 x double>] %"x'", 0
; CHECK-NEXT:    %1 = extractvalue [3 x <2 x double>] %"x'", 1
; CHECK-NEXT:    %2 = extractvalue [3 x <2 x double>] %"x'", 2
; CHECK-NEXT:    %3 = {{(fsub fast <2 x double> <double \-0.000000e\+00, double \-0.000000e\+00>,|fneg fast <2 x double>)}} %0
; CHECK-NEXT:    %4 = select{{( fast)?}} <2 x i1> <i1 false, i1 true>, <2 x double> %0, <2 x double> %3
; CHECK-NEXT:    %5 = {{(fsub fast <2 x double> <double \-0.000000e\+00, double \-0.000000e\+00>,|fneg fast <2 x double>)}} %1
; CHECK-NEXT:    %6 = select{{( fast)?}} <2 x i1> <i1 false, i1 true>, <2 x double> %1, <2 x double> %5
; CHECK-NEXT:    %7 = {{(fsub fast <2 x double> <double \-0.000000e\+00, double \-0.000000e\+00>,|fneg fast <2 x double>)}} %2
; CHECK-NEXT:    %8 = select{{( fast)?}} <2 x i1> <i1 false, i1 true>, <2 x double> %2, <2 x double> %7
; CHECK-NEXT:    %9 = insertvalue [3 x <2 x double>] undef, <2 x double> %4, 0
; CHECK-NEXT:    %10 = insertvalue [3 x <2 x double>] %9, <2 x double> %6, 1
; CHECK-NEXT:    %11 = insertvalue [3 x <2 x double>] %10, <2 x double> %8, 2
; CHECK-NEXT:    ret [3 x <2 x double>] %11
