@@ -43,19 +43,23 @@ module stage2_fwd
43
43
g (x) = Diffractor.∂☆ {1} ()(Diffractor. ZeroBundle {1} (f), Diffractor. TaylorBundle {1} (x, (1.0 ,)))
44
44
Diffractor.∂☆ {1} ()(Diffractor. ZeroBundle {1} (g), Diffractor. TaylorBundle {1} (10f0 , (1.0 ,)))
45
45
end
46
+ end
47
+
46
48
49
+ module forward_diff_no_inf # todo: move this to a seperate file
50
+ using Diffractor, Test
51
+ # this is needed as transform! is *always* called on Arguments regardless of what visit_custom says
52
+ identity_transform! (ir, ssa:: Core.SSAValue , order) = ir[ssa]
53
+ function identity_transform! (ir, arg:: Core.Argument , order)
54
+ return Core. Compiler. insert_node! (ir, Core. SSAValue (1 ), Core. Compiler. NewInstruction (Expr (:call , Diffractor. ZeroBundle{1 }, arg), Any))
55
+ end
56
+
47
57
@testset " Constructors in forward_diff_no_inf!" begin
48
58
struct Bar148
49
59
v
50
60
end
51
61
foo_148 (x) = Bar148 (x)
52
62
53
- # this is needed as transform! is *always* called on Arguments regardless of what visit_custom says
54
- identity_transform! (ir, ssa:: Core.SSAValue , order) = ir[ssa]
55
- function identity_transform! (ir, arg:: Core.Argument , order)
56
- return Core. Compiler. insert_node! (ir, Core. SSAValue (1 ), Core. Compiler. NewInstruction (Expr (:call , Diffractor. ZeroBundle{1 }, arg), Any))
57
- end
58
-
59
63
ir = first (only (Base. code_ircode (foo_148, Tuple{Float64})))
60
64
Diffractor. forward_diff_no_inf! (ir, [Core. SSAValue (1 ) => 1 ]; transform! = identity_transform!)
61
65
ir2 = Core. Compiler. compact! (ir)
@@ -67,17 +71,39 @@ module stage2_fwd
67
71
@eval global _coeff:: Float64 = 24.5
68
72
plus_a_global (x) = x + _coeff
69
73
70
- # this is needed as transform! is *always* called on Arguments regardless of what visit_custom says
71
- identity_transform! (ir, ssa:: Core.SSAValue , order) = ir[ssa]
72
- function identity_transform! (ir, arg:: Core.Argument , order)
73
- return Core. Compiler. insert_node! (ir, Core. SSAValue (1 ), Core. Compiler. NewInstruction (Expr (:call , Diffractor. ZeroBundle{1 }, arg), Any))
74
- end
75
-
76
74
ir = first (only (Base. code_ircode (plus_a_global, Tuple{Float64})))
77
75
Diffractor. forward_diff_no_inf! (ir, [Core. SSAValue (1 ) => 1 ]; transform! = identity_transform!)
78
76
ir2 = Core. Compiler. compact! (ir)
79
77
Core. Compiler. verify_ir (ir2) # This would error if we were not handling nonconst globals correctly
80
78
f = Core. OpaqueClosure (ir2; do_compile= false )
81
79
@test f (3.5 ) == 28.0
82
80
end
81
+
82
+ @testset " runs of phi nodes" begin
83
+ function phi_run (x:: Float64 )
84
+ a = 2.0
85
+ b = 2.0
86
+ if (@noinline rand ()) < 0 # this branch will never actually be taken
87
+ a = - 100.0
88
+ b = 200.0
89
+ end
90
+ return x - a + b
91
+ end
92
+
93
+ input_ir = first (only (Base. code_ircode (phi_run, Tuple{Float64})))
94
+ ir = copy (input_ir)
95
+ # Workout where to diff to trigger error
96
+ diff_ssa = Core. SSAValue[]
97
+ for idx in 1 : length (ir. stmts)
98
+ if ir. stmts[idx][:inst ] isa Core. PhiNode
99
+ push! (diff_ssa, Core. SSAValue (idx))
100
+ end
101
+ end
102
+
103
+ Diffractor. forward_diff_no_inf! (ir, diff_ssa .=> 1 ; transform! = identity_transform!)
104
+ ir2 = Core. Compiler. compact! (ir)
105
+ Core. Compiler. verify_ir (ir2) # This would error if we were not handling nonconst phi nodes correctly (after https://github.com/JuliaLang/julia/pull/50158)
106
+ f = Core. OpaqueClosure (ir2; do_compile= false )
107
+ @test f (3.5 ) == 3.5 # this will segfault if we are not handling phi nodes correctly
108
+ end
83
109
end
0 commit comments