Skip to content

Commit 74a303a

Browse files
elliotttfitzgen
andauthored
Guard recursion in will_simplify_with_ireduce (#7882)
Add a test to expose issues with unbounded recursion through `iadd` during egraph rewrites, and bound the recursion of `will_simplify_with_ireduce`. Fixes #7874 Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
1 parent 7d0bdcc commit 74a303a

2 files changed

Lines changed: 55 additions & 9 deletions

File tree

cranelift/codegen/src/opts/extends.isle

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,26 @@
7777

7878
;; Matches values where `ireducing` them will not actually introduce another
7979
;; instruction, since other rules will collapse them with the reduction.
80-
(decl pure multi will_simplify_with_ireduce (Value) Value)
81-
(rule (will_simplify_with_ireduce x@(uextend _ _)) x)
82-
(rule (will_simplify_with_ireduce x@(sextend _ _)) x)
83-
(rule (will_simplify_with_ireduce x@(iconst _ _)) x)
84-
(rule (will_simplify_with_ireduce x@(unary_op _ _ a))
85-
(if-let _ (will_simplify_with_ireduce a))
80+
(decl pure multi will_simplify_with_ireduce_rec (u8 Value) Value)
81+
(rule (will_simplify_with_ireduce_rec _ x@(uextend _ _)) x)
82+
(rule (will_simplify_with_ireduce_rec _ x@(sextend _ _)) x)
83+
(rule (will_simplify_with_ireduce_rec _ x@(iconst _ _)) x)
84+
(rule (will_simplify_with_ireduce_rec depth x@(unary_op _ _ a))
85+
(if-let _ (u8_lt 0 depth))
86+
(if-let _ (reducible_modular_op x))
87+
(if-let _ (will_simplify_with_ireduce_rec (u8_sub depth 1) a))
8688
x)
87-
(rule (will_simplify_with_ireduce x@(binary_op _ _ a b))
88-
(if-let _ (will_simplify_with_ireduce a))
89-
(if-let _ (will_simplify_with_ireduce b))
89+
(rule (will_simplify_with_ireduce_rec depth x@(binary_op _ _ a b))
90+
(if-let _ (u8_lt 0 depth))
91+
(if-let _ (reducible_modular_op x))
92+
(if-let _ (will_simplify_with_ireduce_rec (u8_sub depth 1) a))
93+
(if-let _ (will_simplify_with_ireduce_rec (u8_sub depth 1) b))
9094
x)
9195

96+
(decl pure multi will_simplify_with_ireduce (Value) Value)
97+
(rule (will_simplify_with_ireduce x)
98+
(will_simplify_with_ireduce_rec 2 x))
99+
92100
;; Matches values where the high bits of the input don't affect lower bits of
93101
;; the output, and thus the inputs can be reduced before the operation rather
94102
;; than doing the wide operation then reducing afterwards.

cranelift/filetests/filetests/egraph/associative-and-commutative.clif

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,41 @@ block0(v0: i32, v1: i32, v2: i32, v3: i32):
7979
; nextln: v8 = bxor v4, v7
8080
; check: return v8
8181
}
82+
83+
;; We don't have any assertions about the result of optimizing this function,
84+
;; but it's a good canary for unbounded recursion in optimization rulesets. In
85+
;; particular, because of the shared structure in the dag, it won't be obvious
86+
;; to rules that are pattern matching on trees that this is actually a chain,
87+
;; and they will exhibit exponential behavior as a result.
88+
function %iadd_big_chain(i8) -> i16 {
89+
block0(v0: i8):
90+
v1 = uextend.i32 v0
91+
v2 = iconst.i32 42
92+
v3 = iadd v1, v2
93+
v4 = iadd v3, v3
94+
v5 = iadd v4, v4
95+
v6 = iadd v5, v5
96+
v7 = iadd v6, v6
97+
v8 = iadd v7, v7
98+
v9 = iadd v8, v8
99+
v10 = iadd v9, v9
100+
v11 = iadd v10, v10
101+
v12 = iadd v11, v11
102+
v13 = iadd v12, v12
103+
v14 = iadd v13, v13
104+
v15 = iadd v14, v14
105+
v16 = iadd v15, v15
106+
v17 = iadd v16, v16
107+
v18 = iadd v17, v17
108+
v19 = iadd v18, v18
109+
v20 = iadd v19, v19
110+
v21 = iadd v20, v20
111+
v22 = iadd v21, v21
112+
v23 = iadd v22, v22
113+
v24 = iadd v23, v23
114+
v25 = iadd v24, v24
115+
v26 = iadd v25, v25
116+
v27 = iadd v26, v26
117+
v28 = ireduce.i16 v27
118+
return v28
119+
}

0 commit comments

Comments
 (0)