@@ -3,6 +3,7 @@ module SIMDTest
33using Test
44using ForwardDiff: Dual, valtype
55using InteractiveUtils: code_llvm
6+ using StaticArrays: SVector
67
78const DUALS = (Dual (1. , 2. , 3. , 4. ),
89 Dual (1. , 2. , 3. , 4. , 5. ),
@@ -17,7 +18,7 @@ function simd_sum(x::Vector{T}) where T
1718 return s
1819end
1920
20- for D in map (typeof, DUALS)
21+ @testset " SIMD $D " for D in map (typeof, DUALS)
2122 plus_bitcode = sprint (io -> code_llvm (io, + , (D, D)))
2223 @test occursin (" fadd <4 x double>" , plus_bitcode)
2324
@@ -32,6 +33,9 @@ for D in map(typeof, DUALS)
3233 @test occursin (r" fadd \< .*?x double\> " , div_bitcode)
3334 @test occursin (r" fmul \< .*?x double\> " , div_bitcode)
3435
36+ pow_bitcode = sprint (io -> code_llvm (io, ^ , (D, Int)))
37+ @test occursin (r" fmul \< .*?x double\> " , pow_bitcode)
38+
3539 exp_bitcode = sprint (io -> code_llvm (io, ^ , (D, D)))
3640 @test occursin (r" fadd \< .*?x double\> " , exp_bitcode)
3741 if ! (valtype (D) <: Dual )
@@ -44,4 +48,26 @@ for D in map(typeof, DUALS)
4448 end
4549end
4650
51+ # `pow2dot` is chosen so that `@code_llvm pow2dot(SVector(1:1.0:4...))`
52+ # generates code with SIMD instructions.
53+ # See:
54+ # https://github.com/JuliaDiff/ForwardDiff.jl/pull/332
55+ # https://github.com/JuliaDiff/ForwardDiff.jl/pull/331#issuecomment-406107260
56+ @inline pow2 (x) = x^ 2
57+ pow2dot (xs) = pow2 .(xs)
58+
59+ # Nested dual such as `Dual(Dual(1., 2.), Dual(3., 4.))` only produces
60+ # "fmul <2 x double>" so it is excluded from the following test.
61+ const POW_DUALS = (Dual (1. , 2. ),
62+ Dual (1. , 2. , 3. ),
63+ Dual (1. , 2. , 3. , 4. ),
64+ Dual (1. , 2. , 3. , 4. , 5. ))
65+
66+ @testset " SIMD square of $D " for D in map (typeof, POW_DUALS)
67+ pow_bitcode = sprint (io -> code_llvm (io, pow2dot, (SVector{4 , D},)))
68+ @test occursin (r" (.*fmul \< 4 x double\> ){2}" s , pow_bitcode)
69+ # "{2}" is for asserting that fmul has to appear at least twice:
70+ # once for `.value` and once for `.partials`.
71+ end
72+
4773end # module
0 commit comments