blob: 8727f5f977636ddbba40015768bda589cb867b8c [file] [edit]
// RUN: %eopt --enzyme --canonicalize --remove-unnecessary-enzyme-ops %s | FileCheck %s
// What enzyme.fwddiff names is not always a func.func. Anything raised from
// LLVM gives an llvm.func, and forward mode turned that down twice over: the
// verifier looked the callee up as a func.func, and the pass wrote a func.call
// to whatever came back. enzyme.autodiff has always taken either.
module {
llvm.func @square(%x: f64) -> f64 {
%r = arith.mulf %x, %x : f64
llvm.return %r : f64
}
llvm.func @dsquare(%x: f64, %dx: f64) -> f64 {
%r = enzyme.fwddiff @square(%x, %dx) { activity=[#enzyme<activity enzyme_dup>], ret_activity=[#enzyme<activity enzyme_dupnoneed>] } : (f64, f64) -> f64
llvm.return %r : f64
}
}
// The derivative is an llvm.func too, and is called as one.
// CHECK: llvm.func @dsquare(%[[x:.+]]: f64, %[[dx:.+]]: f64) -> f64
// CHECK: %[[c:.+]] = llvm.call @fwddiffesquare(%[[x]], %[[dx]]) : (f64, f64) -> f64
// CHECK: llvm.return %[[c]] : f64
// CHECK: llvm.func @fwddiffesquare(%[[px:.+]]: f64, %[[pdx:.+]]: f64) -> f64
// CHECK: %[[a:.+]] = arith.mulf %[[pdx]], %[[px]] fastmath<fast> : f64
// CHECK: %[[b:.+]] = arith.mulf %[[pdx]], %[[px]] fastmath<fast> : f64
// CHECK: %[[s:.+]] = arith.addf %[[a]], %[[b]] fastmath<fast> : f64
// CHECK: llvm.return %[[s]] : f64