Skip to content

Commit c7bc24c

Browse files
authored
ForwardMode IntrinsicInst (rust-lang#300)
* implement intrinsicInst * add tests
1 parent 841c0bf commit c7bc24c

19 files changed

+949
-4
lines changed

enzyme/Enzyme/AdjointGenerator.h

+400-4
Large diffs are not rendered by default.

enzyme/test/Enzyme/ForwardMode/cos.ll

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -O3 -S | FileCheck %s
2+
3+
; Function Attrs: nounwind readnone uwtable
4+
define double @tester(double %x) {
5+
entry:
6+
%0 = tail call fast double @llvm.cos.f64(double %x)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x) {
11+
entry:
12+
%0 = tail call double (double (double)*, ...) @__enzyme_fwddiff(double (double)* nonnull @tester, double %x, double 1.0)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.cos.f64(double)
18+
19+
; Function Attrs: nounwind readnone speculatable
20+
declare double @llvm.sin.f64(double)
21+
22+
; Function Attrs: nounwind
23+
declare double @__enzyme_fwddiff(double (double)*, ...)
24+
25+
; CHECK: define double @test_derivative(double %x)
26+
; CHECK-NEXT: entry:
27+
; CHECK-NEXT: %0 = tail call fast double @llvm.sin.f64(double %x)
28+
; CHECK-NEXT: %1 = {{(fsub fast double -0.000000e\+00,|fneg fast double)}} %0
29+
; CHECK-NEXT: ret double %1
30+
; CHECK-NEXT: }

enzyme/test/Enzyme/ForwardMode/exp.ll

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -O3 -S | FileCheck %s
2+
3+
; Function Attrs: nounwind readnone uwtable
4+
define double @tester(double %x) {
5+
entry:
6+
%0 = tail call fast double @llvm.exp.f64(double %x)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x) {
11+
entry:
12+
%0 = tail call double (double (double)*, ...) @__enzyme_fwddiff(double (double)* nonnull @tester, double %x, double 1.0)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.exp.f64(double)
18+
19+
; Function Attrs: nounwind
20+
declare double @__enzyme_fwddiff(double (double)*, ...)
21+
22+
; CHECK: define double @test_derivative(double %x)
23+
; CHECK-NEXT: entry:
24+
; CHECK-NEXT: %0 = tail call fast double @llvm.exp.f64(double %x)
25+
; CHECK-NEXT: ret double %0
26+
; CHECK-NEXT: }
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -O3 -S | FileCheck %s
2+
3+
; Function Attrs: nounwind readnone uwtable
4+
define double @tester(double %x) {
5+
entry:
6+
%0 = tail call fast double @llvm.exp2.f64(double %x)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x) {
11+
entry:
12+
%0 = tail call double (double (double)*, ...) @__enzyme_fwddiff(double (double)* nonnull @tester, double %x, double 1.0)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.exp2.f64(double)
18+
19+
; Function Attrs: nounwind
20+
declare double @__enzyme_fwddiff(double (double)*, ...)
21+
22+
; CHECK: define double @test_derivative(double %x)
23+
; CHECK-NEXT: entry:
24+
; CHECK-NEXT: %0 = tail call fast double @llvm.exp2.f64(double %x)
25+
; CHECK-NEXT: %1 = fmul fast double %0, 0x3FE62E42FEFA39EF
26+
; CHECK-NEXT: ret double %1
27+
; CHECK-NEXT: }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: if [ %llvmver -ge 9 ] && [ %llvmver -le 11 ]; then %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -mem2reg -instsimplify -simplifycfg -S | FileCheck %s; fi
2+
3+
define float @tester(float %start_value, <4 x float> %input) {
4+
entry:
5+
%ord = call float @llvm.experimental.vector.reduce.v2.fadd.f32.v4f32(float %start_value, <4 x float> %input)
6+
ret float %ord
7+
}
8+
9+
define float @test_derivative(float %start_value, <4 x float> %input) {
10+
entry:
11+
%0 = tail call float (float (float, <4 x float>)*, ...) @__enzyme_fwddiff(float (float, <4 x float>)* nonnull @tester, float %start_value, float 1.0, <4 x float> %input, <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>)
12+
ret float %0
13+
}
14+
15+
declare float @llvm.experimental.vector.reduce.v2.fadd.f32.v4f32(float, <4 x float>)
16+
17+
; Function Attrs: nounwind
18+
declare float @__enzyme_fwddiff(float (float, <4 x float>)*, ...)
19+
20+
21+
; CHECK: define internal {{(dso_local )?}}{ float } @diffetester(float %start_value, float %"start_value'", <4 x float> %input, <4 x float> %"input'")
22+
; CHECK-NEXT: entry:
23+
; CHECK-NEXT: %0 = call fast float @llvm.experimental.vector.reduce.v2.fadd.f32.v4f32(float %"start_value'", <4 x float> %"input'")
24+
; CHECK-NEXT: %1 = insertvalue { float } undef, float %0, 0
25+
; CHECK-NEXT: ret { float } %1
26+
; CHECK-NEXT: }
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -mem2reg -early-cse -simplifycfg -S | FileCheck %s
2+
3+
; Function Attrs: nounwind readnone uwtable
4+
define double @tester(double %x) {
5+
entry:
6+
%0 = tail call fast double @llvm.fabs.f64(double %x)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x) {
11+
entry:
12+
%0 = tail call double (double (double)*, ...) @__enzyme_fwddiff(double (double)* nonnull @tester, double %x, double 1.0)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.fabs.f64(double)
18+
19+
; Function Attrs: nounwind
20+
declare double @__enzyme_fwddiff(double (double)*, ...)
21+
22+
; CHECK: define internal {{(dso_local )?}}{ double } @diffetester(double %x, double %[[differet:.+]])
23+
; CHECK-NEXT: entry:
24+
; CHECK-NEXT: %0 = fcmp fast olt double %x, 0.000000e+00
25+
; CHECK-NEXT: %1 = select{{( fast)?}} i1 %0, double -1.000000e+00, double 1.000000e+00
26+
; CHECK-NEXT: %2 = fmul fast double %1, %[[differet]]
27+
; CHECK-NEXT: %3 = insertvalue { double } undef, double %2, 0
28+
; CHECK-NEXT: ret { double } %3
29+
; CHECK-NEXT: }

enzyme/test/Enzyme/ForwardMode/log.ll

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -O3 -S | FileCheck %s
2+
3+
; Function Attrs: nounwind readnone uwtable
4+
define double @tester(double %x) {
5+
entry:
6+
%0 = tail call fast double @llvm.log.f64(double %x)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x) {
11+
entry:
12+
%0 = tail call double (double (double)*, ...) @__enzyme_fwddiff(double (double)* nonnull @tester, double %x, double 1.0)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.log.f64(double)
18+
19+
; Function Attrs: nounwind
20+
declare double @__enzyme_fwddiff(double (double)*, ...)
21+
22+
; CHECK: define double @test_derivative(double %x)
23+
; CHECK-NEXT: entry:
24+
; CHECK-NEXT: %0 = fdiv fast double 1.000000e+00, %x
25+
; CHECK-NEXT: ret double %0
26+
; CHECK-NEXT: }
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -O3 -S | FileCheck %s
2+
3+
; Function Attrs: nounwind readnone uwtable
4+
define double @tester(double %x) {
5+
entry:
6+
%0 = tail call fast double @llvm.log10.f64(double %x)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x) {
11+
entry:
12+
%0 = tail call double (double (double)*, ...) @__enzyme_fwddiff(double (double)* nonnull @tester, double %x, double 1.0)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.log10.f64(double)
18+
19+
; Function Attrs: nounwind
20+
declare double @__enzyme_fwddiff(double (double)*, ...)
21+
22+
; CHECK: define double @test_derivative(double %x)
23+
; CHECK-NEXT: entry:
24+
; equivalent to 1/log(10) / x
25+
; CHECK-NEXT: %0 = fdiv fast double 0x3FDBCB7B1526E50D, %x
26+
; CHECK-NEXT: ret double %0
27+
; CHECK-NEXT: }
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -O3 -S | FileCheck %s
2+
3+
; Function Attrs: nounwind readnone uwtable
4+
define double @tester(double %x) {
5+
entry:
6+
%0 = tail call fast double @llvm.log2.f64(double %x)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x) {
11+
entry:
12+
%0 = tail call double (double (double)*, ...) @__enzyme_fwddiff(double (double)* nonnull @tester, double %x, double 1.0)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.log2.f64(double)
18+
19+
; Function Attrs: nounwind
20+
declare double @__enzyme_fwddiff(double (double)*, ...)
21+
22+
; CHECK: define double @test_derivative(double %x)
23+
; CHECK-NEXT: entry:
24+
; equivalent to 1/log(2) / x
25+
; CHECK-NEXT: %0 = fdiv fast double 0x3FF71547652B82FE, %x
26+
; CHECK-NEXT: ret double %0
27+
; CHECK-NEXT: }
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -mem2reg -early-cse -simplifycfg -S | FileCheck %s
2+
3+
; Function Attrs: noinline nounwind readnone uwtable
4+
define double @tester(double %x, double %y) {
5+
entry:
6+
%0 = tail call double @llvm.maxnum.f64(double %x, double %y)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x, double %y) {
11+
entry:
12+
%0 = tail call double (double (double, double)*, ...) @__enzyme_fwddiff(double (double, double)* nonnull @tester, double %x, double 1.0, double %y, double 1.0)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.maxnum.f64(double, double)
18+
19+
; Function Attrs: nounwind
20+
declare double @__enzyme_fwddiff(double (double, double)*, ...)
21+
22+
; CHECK: define internal {{(dso_local )?}}{ double } @diffetester(double %x, double %"x'", double %y, double %"y'")
23+
; CHECK-NEXT: entry:
24+
; CHECK-NEXT: %0 = fcmp fast olt double %x, %y
25+
; CHECK-NEXT: %1 = select {{(fast )?}}i1 %0, double %"x'", double %"y'"
26+
; CHECK-NEXT: %2 = insertvalue { double } undef, double %1, 0
27+
; CHECK-NEXT: ret { double } %2
28+
; CHECK-NEXT: }
29+
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -mem2reg -early-cse -simplifycfg -S | FileCheck %s
2+
3+
define double @tester(double %x, double %y) {
4+
entry:
5+
%0 = tail call double @llvm.minnum.f64(double %x, double %y)
6+
ret double %0
7+
}
8+
9+
define double @test_derivative(double %x, double %y) {
10+
entry:
11+
%0 = tail call double (double (double, double)*, ...) @__enzyme_fwddiff(double (double, double)* nonnull @tester, double %x, double 1.0, double %y, double 1.0)
12+
ret double %0
13+
}
14+
15+
declare double @llvm.minnum.f64(double, double)
16+
17+
declare double @__enzyme_fwddiff(double (double, double)*, ...)
18+
19+
; CHECK: define internal {{(dso_local )?}}{ double } @diffetester(double %x, double %"x'", double %y, double %"y'")
20+
; CHECK-NEXT: entry:
21+
; CHECK-NEXT: %0 = fcmp fast olt double %x, %y
22+
; CHECK-NEXT: %1 = select{{( fast)?}} i1 %0, double %"x'", double %"y'"
23+
; CHECK-NEXT: %2 = insertvalue { double } undef, double %1, 0
24+
; CHECK-NEXT: ret { double } %2
25+
; CHECK-NEXT: }

enzyme/test/Enzyme/ForwardMode/pow.ll

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -mem2reg -instsimplify -simplifycfg -S | FileCheck %s
2+
3+
; Function Attrs: noinline nounwind readnone uwtable
4+
define double @tester(double %x, double %y) {
5+
entry:
6+
%0 = tail call fast double @llvm.pow.f64(double %x, double %y)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x, double %y) {
11+
entry:
12+
%0 = tail call double (double (double, double)*, ...) @__enzyme_fwddiff(double (double, double)* nonnull @tester, double %x, double 1.0, double %y, double 1.0)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.pow.f64(double, double)
18+
19+
; Function Attrs: nounwind
20+
declare double @__enzyme_fwddiff(double (double, double)*, ...)
21+
22+
; CHECK: define internal {{(dso_local )?}}{ double } @diffetester(double %x, double %"x'", double %y, double %"y'") {
23+
; CHECK-NEXT: entry:
24+
; CHECK-NEXT: %0 = fsub fast double %y, 1.000000e+00
25+
; CHECK-NEXT: %1 = call fast double @llvm.pow.f64(double %x, double %0)
26+
; CHECK-NEXT: %2 = fmul fast double %y, %1
27+
; CHECK-NEXT: %3 = call fast double @llvm.pow.f64(double %x, double %y)
28+
; CHECK-NEXT: %4 = call fast double @llvm.log.f64(double %x)
29+
; CHECK-DAG: %5 = fmul fast double %3, %4
30+
; CHECK-DAG: %6 = fadd fast double %2, %5
31+
; CHECK-NEXT: %7 = insertvalue { double } undef, double %6, 0
32+
; CHECK-NEXT: ret { double } %7
33+
; CHECK-NEXT: }
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -mem2reg -instsimplify -simplifycfg -S | FileCheck %s
2+
3+
; Function Attrs: noinline nounwind readnone uwtable
4+
define double @tester(double %x, i32 %y) {
5+
entry:
6+
%0 = tail call fast double @llvm.powi.f64(double %x, i32 %y)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x, i32 %y) {
11+
entry:
12+
%0 = tail call double (double (double, i32)*, ...) @__enzyme_fwddiff(double (double, i32)* nonnull @tester, double %x, double 1.0, i32 %y)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.powi.f64(double, i32)
18+
19+
; Function Attrs: nounwind
20+
declare double @__enzyme_fwddiff(double (double, i32)*, ...)
21+
22+
; CHECK: define internal {{(dso_local )?}}{ double } @diffetester(double %x, double %"x'", i32 %y) {
23+
; CHECK-NEXT: entry:
24+
; CHECK-NEXT: %[[ym1:.+]] = sub i32 %y, 1
25+
; CHECK-NEXT: %[[newpow:.+]] = call fast double @llvm.powi.f64(double %x, i32 %[[ym1]])
26+
; CHECK-DAG: %[[sitofp:.+]] = sitofp i32 %y to double
27+
; CHECK-DAG: %[[newpowdret:.+]] = fmul fast double %"x'", %[[newpow]]
28+
; CHECK-NEXT: %[[dx:.+]] = fmul fast double %[[newpowdret]], %[[sitofp]]
29+
; CHECK-NEXT: %[[interres:.+]] = insertvalue { double } undef, double %[[dx:.+]], 0
30+
; CHECK-NEXT: ret { double } %[[interres]]
31+
; CHECK-NEXT: }
32+

enzyme/test/Enzyme/ForwardMode/sin.ll

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -O3 -S | FileCheck %s
2+
3+
; Function Attrs: nounwind readnone uwtable
4+
define double @tester(double %x) {
5+
entry:
6+
%0 = tail call fast double @llvm.sin.f64(double %x)
7+
ret double %0
8+
}
9+
10+
define double @test_derivative(double %x) {
11+
entry:
12+
%0 = tail call double (double (double)*, ...) @__enzyme_autodiff(double (double)* nonnull @tester, double %x)
13+
ret double %0
14+
}
15+
16+
; Function Attrs: nounwind readnone speculatable
17+
declare double @llvm.cos.f64(double)
18+
19+
; Function Attrs: nounwind readnone speculatable
20+
declare double @llvm.sin.f64(double)
21+
22+
; Function Attrs: nounwind
23+
declare double @__enzyme_autodiff(double (double)*, ...)
24+
25+
; CHECK: define double @test_derivative(double %x)
26+
; CHECK-NEXT: entry:
27+
; CHECK-NEXT: %0 = tail call fast double @llvm.cos.f64(double %x)
28+
; CHECK-NEXT: ret double %0
29+
; CHECK-NEXT: }

0 commit comments

Comments
 (0)