|
| 1 | +; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -mem2reg -S | FileCheck %s |
| 2 | + |
| 3 | +define void @tester(double* %in0, double* %in1, i1 %c) { |
| 4 | +entry: |
| 5 | + br i1 %c, label %trueb, label %exit |
| 6 | + |
| 7 | +trueb: |
| 8 | + %pre_x0 = load double, double* %in0 |
| 9 | + store double 0.000000e+00, double* %in0 |
| 10 | + %x0 = insertvalue {double, double, double*} undef, double %pre_x0, 0 |
| 11 | + |
| 12 | + %pre_x1 = load double, double* %in1 |
| 13 | + store double 0.000000e+00, double* %in1 |
| 14 | + %x1 = insertvalue {double, double, double*} %x0, double %pre_x1, 1 |
| 15 | + |
| 16 | + %out1 = insertvalue {double, double, double*} %x1, double* %in0, 2 |
| 17 | + |
| 18 | + %post_x0 = extractvalue {double, double, double*} %out1, 0 |
| 19 | + %post_x1 = extractvalue {double, double, double*} %x1, 1 |
| 20 | + |
| 21 | + %mul0 = fmul double %post_x0, %post_x1 |
| 22 | + store double %mul0, double* %in0 |
| 23 | + |
| 24 | + br label %exit |
| 25 | + |
| 26 | +exit: |
| 27 | + ret void |
| 28 | +} |
| 29 | + |
| 30 | +define void @test_derivative(double* %x, double* %dx, double* %y, double* %dy) { |
| 31 | +entry: |
| 32 | + tail call void (...) @__enzyme_autodiff(void (double*, double*, i1)* nonnull @tester, double* %x, double* %dx, double* %y, double* %dy, i1 true) |
| 33 | + ret void |
| 34 | +} |
| 35 | + |
| 36 | +; Function Attrs: nounwind |
| 37 | +declare void @__enzyme_autodiff(...) |
| 38 | + |
| 39 | +; CHECK: define internal void @diffetester(double* %in0, double* %"in0'", double* %in1, double* %"in1'", i1 %c) |
| 40 | +; CHECK-NEXT: entry: |
| 41 | +; CHECK-NEXT: %"x1'de" = alloca { double, double, double* } |
| 42 | +; CHECK-NEXT: store { double, double, double* } zeroinitializer, { double, double, double* }* %"x1'de" |
| 43 | +; CHECK-NEXT: %"out1'de" = alloca { double, double, double* } |
| 44 | +; CHECK-NEXT: store { double, double, double* } zeroinitializer, { double, double, double* }* %"out1'de" |
| 45 | +; CHECK-NEXT: %"x0'de" = alloca { double, double, double* } |
| 46 | +; CHECK-NEXT: store { double, double, double* } zeroinitializer, { double, double, double* }* %"x0'de" |
| 47 | +; CHECK-NEXT: br i1 %c, label %trueb, label %exit |
| 48 | + |
| 49 | +; CHECK: trueb: ; preds = %entry |
| 50 | +; CHECK-NEXT: %pre_x0 = load double, double* %in0 |
| 51 | +; CHECK-NEXT: store double 0.000000e+00, double* %in0 |
| 52 | +; CHECK-NEXT: %x0 = insertvalue { double, double, double* } undef, double %pre_x0, 0 |
| 53 | +; CHECK-NEXT: %pre_x1 = load double, double* %in1 |
| 54 | +; CHECK-NEXT: store double 0.000000e+00, double* %in1 |
| 55 | +; CHECK-NEXT: %x1 = insertvalue { double, double, double* } %x0, double %pre_x1, 1 |
| 56 | +; CHECK-NEXT: %out1 = insertvalue { double, double, double* } %x1, double* %in0, 2 |
| 57 | +; CHECK-NEXT: %post_x0 = extractvalue { double, double, double* } %out1, 0 |
| 58 | +; CHECK-NEXT: %post_x1 = extractvalue { double, double, double* } %x1, 1 |
| 59 | +; CHECK-NEXT: %mul0 = fmul double %post_x0, %post_x1 |
| 60 | +; CHECK-NEXT: store double %mul0, double* %in0 |
| 61 | +; CHECK-NEXT: br label %exit |
| 62 | + |
| 63 | +; CHECK: exit: ; preds = %trueb, %entry |
| 64 | +; CHECK-NEXT: %x1_cache.0 = phi { double, double, double* } [ %x1, %trueb ], [ undef, %entry ] |
| 65 | +; CHECK-NEXT: br label %invertexit |
| 66 | + |
| 67 | +; CHECK: invertentry: ; preds = %invertexit, %inverttrueb |
| 68 | +; CHECK-NEXT: ret void |
| 69 | + |
| 70 | +; CHECK: inverttrueb: ; preds = %invertexit |
| 71 | +; CHECK-NEXT: %0 = load double, double* %"in0'" |
| 72 | +; CHECK-NEXT: store double 0.000000e+00, double* %"in0'" |
| 73 | +; CHECK-NEXT: %1 = fadd fast double 0.000000e+00, %0 |
| 74 | +; CHECK-NEXT: %post_x1_unwrap = extractvalue { double, double, double* } %x1_cache.0, 1 |
| 75 | +; CHECK-NEXT: %m0diffepost_x0 = fmul fast double %1, %post_x1_unwrap |
| 76 | +; CHECK-NEXT: %out1_unwrap = insertvalue { double, double, double* } %x1_cache.0, double* %in0, 2 |
| 77 | +; CHECK-NEXT: %post_x0_unwrap = extractvalue { double, double, double* } %out1_unwrap, 0 |
| 78 | +; CHECK-NEXT: %m1diffepost_x1 = fmul fast double %1, %post_x0_unwrap |
| 79 | +; CHECK-NEXT: %2 = fadd fast double 0.000000e+00, %m0diffepost_x0 |
| 80 | +; CHECK-NEXT: %3 = fadd fast double 0.000000e+00, %m1diffepost_x1 |
| 81 | +; CHECK-NEXT: %4 = getelementptr inbounds { double, double, double* }, { double, double, double* }* %"x1'de", i32 0, i32 1 |
| 82 | +; CHECK-NEXT: %5 = load double, double* %4 |
| 83 | +; CHECK-NEXT: %6 = fadd fast double %5, %3 |
| 84 | +; CHECK-NEXT: store double %6, double* %4 |
| 85 | +; CHECK-NEXT: %7 = getelementptr inbounds { double, double, double* }, { double, double, double* }* %"out1'de", i32 0, i32 0 |
| 86 | +; CHECK-NEXT: %8 = load double, double* %7 |
| 87 | +; CHECK-NEXT: %9 = fadd fast double %8, %2 |
| 88 | +; CHECK-NEXT: store double %9, double* %7 |
| 89 | +; CHECK-NEXT: %10 = load { double, double, double* }, { double, double, double* }* %"out1'de" |
| 90 | +; CHECK-NEXT: %11 = insertvalue { double, double, double* } %10, double* null, 2 |
| 91 | +; CHECK-NEXT: %12 = load { double, double, double* }, { double, double, double* }* %"x1'de" |
| 92 | +; CHECK-NEXT: %13 = extractvalue { double, double, double* } %10, 0 |
| 93 | +; CHECK-NEXT: %14 = getelementptr inbounds { double, double, double* }, { double, double, double* }* %"x1'de", i32 0, i32 0 |
| 94 | +; CHECK-NEXT: %15 = load double, double* %14 |
| 95 | +; CHECK-NEXT: %16 = fadd fast double %15, %13 |
| 96 | +; CHECK-NEXT: store double %16, double* %14 |
| 97 | +; CHECK-NEXT: %17 = extractvalue { double, double, double* } %10, 1 |
| 98 | +; CHECK-NEXT: %18 = getelementptr inbounds { double, double, double* }, { double, double, double* }* %"x1'de", i32 0, i32 1 |
| 99 | +; CHECK-NEXT: %19 = load double, double* %18 |
| 100 | +; CHECK-NEXT: %20 = fadd fast double %19, %17 |
| 101 | +; CHECK-NEXT: store double %20, double* %18 |
| 102 | +; CHECK-NEXT: store { double, double, double* } zeroinitializer, { double, double, double* }* %"out1'de" |
| 103 | +; CHECK-NEXT: %21 = load { double, double, double* }, { double, double, double* }* %"x1'de" |
| 104 | +; CHECK-NEXT: %22 = extractvalue { double, double, double* } %21, 1 |
| 105 | +; CHECK-NEXT: %23 = fadd fast double 0.000000e+00, %22 |
| 106 | +; CHECK-NEXT: %24 = load { double, double, double* }, { double, double, double* }* %"x1'de" |
| 107 | +; CHECK-NEXT: %25 = insertvalue { double, double, double* } %24, double 0.000000e+00, 1 |
| 108 | +; CHECK-NEXT: %26 = load { double, double, double* }, { double, double, double* }* %"x0'de" |
| 109 | +; CHECK-NEXT: %27 = extractvalue { double, double, double* } %24, 0 |
| 110 | +; CHECK-NEXT: %28 = getelementptr inbounds { double, double, double* }, { double, double, double* }* %"x0'de", i32 0, i32 0 |
| 111 | +; CHECK-NEXT: %29 = load double, double* %28 |
| 112 | +; CHECK-NEXT: %30 = fadd fast double %29, %27 |
| 113 | +; CHECK-NEXT: store double %30, double* %28 |
| 114 | +; CHECK-NEXT: %31 = getelementptr inbounds { double, double, double* }, { double, double, double* }* %"x0'de", i32 0, i32 1 |
| 115 | +; CHECK-NEXT: %32 = load double, double* %31 |
| 116 | +; CHECK-NEXT: %33 = fadd fast double %32, 0.000000e+00 |
| 117 | +; CHECK-NEXT: store double %33, double* %31 |
| 118 | +; CHECK-NEXT: store { double, double, double* } zeroinitializer, { double, double, double* }* %"x1'de" |
| 119 | +; CHECK-NEXT: store double 0.000000e+00, double* %"in1'" |
| 120 | +; CHECK-NEXT: %34 = load double, double* %"in1'" |
| 121 | +; CHECK-NEXT: %35 = fadd fast double %34, %23 |
| 122 | +; CHECK-NEXT: store double %35, double* %"in1'" |
| 123 | +; CHECK-NEXT: %36 = load { double, double, double* }, { double, double, double* }* %"x0'de" |
| 124 | +; CHECK-NEXT: %37 = extractvalue { double, double, double* } %36, 0 |
| 125 | +; CHECK-NEXT: %38 = fadd fast double 0.000000e+00, %37 |
| 126 | +; CHECK-NEXT: store { double, double, double* } zeroinitializer, { double, double, double* }* %"x0'de" |
| 127 | +; CHECK-NEXT: store double 0.000000e+00, double* %"in0'" |
| 128 | +; CHECK-NEXT: %39 = load double, double* %"in0'" |
| 129 | +; CHECK-NEXT: %40 = fadd fast double %39, %38 |
| 130 | +; CHECK-NEXT: store double %40, double* %"in0'" |
| 131 | +; CHECK-NEXT: br label %invertentry |
| 132 | + |
| 133 | +; CHECK: invertexit: ; preds = %exit |
| 134 | +; CHECK-NEXT: br i1 %c, label %inverttrueb, label %invertentry |
| 135 | +; CHECK-NEXT: } |
0 commit comments