Skip to content

Commit ecd10f0

Browse files
wsmosesvchuravy
andauthored
Add fmod (rust-lang#976)
Co-authored-by: Valentin Churavy <[email protected]>
1 parent 282feae commit ecd10f0

File tree

5 files changed

+98
-0
lines changed

5 files changed

+98
-0
lines changed

enzyme/Enzyme/InstructionDerivatives.td

+8
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,11 @@ def : CallPattern<(Op $x),
171171
[
172172
(FMul (DiffeRet<"">), (FMul (ConstantFP<"2.0"> $x), (FSub (FMul $x, (Call<(SameFunc), [ReadNone,NoUnwind]> $x)), (ConstantFP<"0.56418958354775628694807945156077258584405062932900"> $x) )))
173173
]>;
174+
175+
def : CallPattern<(Op $x, $y),
176+
["fmod", "fmodf", "fmodl"],
177+
[
178+
(DiffeRet<"">),
179+
(FMul (DiffeRet<"">), (FNeg (Intrinsic<"copysign", [(TypeOf<""> $x)]> (Intrinsic<"floor", [(TypeOf<""> $x)]> (Intrinsic<"fabs", [(TypeOf<""> $x)]> (FDiv $x, $y))), (FDiv $x, $y))))
180+
]
181+
>;

enzyme/Enzyme/TypeAnalysis/TypeAnalysis.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ const std::map<std::string, llvm::Intrinsic::ID> LIBM_FUNCTIONS = {
171171
{"powi", Intrinsic::powi},
172172
{"cabs", Intrinsic::not_intrinsic},
173173
{"ldexp", Intrinsic::not_intrinsic},
174+
{"fmod", Intrinsic::not_intrinsic},
174175
#if LLVM_VERSION_MAJOR >= 9
175176
{"lround", Intrinsic::lround},
176177
{"llround", Intrinsic::llround},
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -early-cse -enzyme-preopt=false -S | FileCheck %s
2+
; RUN: if [ %llvmver -ge 12 ]; then %opt < %s %newLoadEnzyme -passes="enzyme,early-cse" -enzyme-preopt=false -S | FileCheck %s ; fi
3+
4+
declare double @fmod(double, double)
5+
6+
define double @tester(double %x, double %y) {
7+
entry:
8+
%0 = call double @fmod(double %x, double %y)
9+
ret double %0
10+
}
11+
12+
define double @test_derivative(double %x, double %y) {
13+
entry:
14+
%0 = tail call double (double (double, double)*, ...) @__enzyme_fwddiff(double (double, double)* nonnull @tester, double %x, double 1.0, double %y, double 1.0)
15+
ret double %0
16+
}
17+
18+
; Function Attrs: nounwind
19+
declare double @__enzyme_fwddiff(double (double, double)*, ...)
20+
21+
22+
; CHECK: define internal double @fwddiffetester(double %x, double %"x'", double %y, double %"y'")
23+
; CHECK-NEXT: entry:
24+
; CHECK-NEXT: %[[i0:.+]] = fdiv fast double %x, %y
25+
; CHECK-NEXT: %[[i1:.+]] = call fast double @llvm.fabs.f64(double %[[i0]])
26+
; CHECK-NEXT: %[[i2:.+]] = call fast double @llvm.floor.f64(double %[[i1]])
27+
; CHECK-NEXT: %[[i3:.+]] = call fast double @llvm.copysign.f64(double %[[i2]], double %[[i0]])
28+
; CHECK-NEXT: %[[i4:.+]] = {{(fsub fast double \-?0.000000e\+00,|fneg fast double)}} %[[i3]]
29+
; CHECK-NEXT: %[[i5:.+]] = fmul fast double %"y'", %[[i4]]
30+
; CHECK-NEXT: %[[i6:.+]] = fadd fast double %"x'", %[[i5]]
31+
; CHECK-NEXT: ret double %[[i6]]
32+
; CHECK-NEXT: }
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; RUN: %opt < %s %loadEnzyme -enzyme -enzyme-preopt=false -S | FileCheck %s
2+
; RUN: %opt < %s %newLoadEnzyme -passes="enzyme" -enzyme-preopt=false -S | FileCheck %s
3+
4+
declare double @fmod(double, double)
5+
6+
define double @tester(double %x, double %y) {
7+
entry:
8+
%0 = call double @fmod(double %x, double 1.000000e+00)
9+
ret double %0
10+
}
11+
12+
define double @test_derivative(double %x, double %y) {
13+
entry:
14+
%0 = tail call double (double (double, double)*, ...) @__enzyme_fwddiff(double (double, double)* nonnull @tester, double %x, double 1.0, double %y, double 1.0)
15+
ret double %0
16+
}
17+
18+
; Function Attrs: nounwind
19+
declare double @__enzyme_fwddiff(double (double, double)*, ...)
20+
21+
22+
; CHECK: define internal double @fwddiffetester(double %x, double %"x'", double %y, double %"y'")
23+
; CHECK-NEXT: entry:
24+
; CHECK-NEXT: ret double %"x'"
25+
; 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 -early-cse -instsimplify -simplifycfg -S | FileCheck %s
2+
3+
declare double @fmod(double, double)
4+
5+
; Function Attrs: noinline nounwind readnone uwtable
6+
define double @tester(double %x, double %y) {
7+
entry:
8+
%0 = call double @fmod(double %x, double %y)
9+
ret double %0
10+
}
11+
12+
define double @test_derivative(double %x, double %y) {
13+
entry:
14+
%0 = tail call double (double (double, double)*, ...) @__enzyme_autodiff(double (double, double)* nonnull @tester, double %x, double %y)
15+
ret double %0
16+
}
17+
18+
; Function Attrs: nounwind
19+
declare double @__enzyme_autodiff(double (double, double)*, ...)
20+
21+
; CHECK: define internal { double, double } @diffetester(double %x, double %y, double %differeturn)
22+
; CHECK-NEXT: entry:
23+
; CHECK-NEXT: %[[i0:.+]] = fdiv fast double %x, %y
24+
; CHECK-NEXT: %[[i1:.+]] = call fast double @llvm.fabs.f64(double %[[i0]])
25+
; CHECK-NEXT: %[[i2:.+]] = call fast double @llvm.floor.f64(double %[[i1]])
26+
; CHECK-NEXT: %[[i3:.+]] = call fast double @llvm.copysign.f64(double %[[i2]], double %[[i0]])
27+
; CHECK-NEXT: %[[i4:.+]] = {{(fsub fast double \-?0.000000e\+00,|fneg fast double)}} %[[i3]]
28+
; CHECK-NEXT: %[[i5:.+]] = fmul fast double %differeturn, %[[i4]]
29+
; CHECK-NEXT: %[[i6:.+]] = insertvalue { double, double } undef, double %differeturn, 0
30+
; CHECK-NEXT: %[[i7:.+]] = insertvalue { double, double } %[[i6]], double %[[i5]], 1
31+
; CHECK-NEXT: ret { double, double } %[[i7]]
32+
; CHECK-NEXT: }

0 commit comments

Comments
 (0)