RFR: 8282592: C2: assert(false) failed: graph should be schedulable
Tobias Hartmann
thartmann at openjdk.java.net
Fri Mar 11 08:09:40 UTC 2022
On Wed, 9 Mar 2022 13:42:01 GMT, Roland Westrelin <roland at openjdk.org> wrote:
> This is another case of overunrolling that causes the type of the main
> loop's iv to conflict with a ConvI2L of an array access. Skeleton
> predicates were added to solve this family of issues. A predicate that
> should catch that the main loop is unreachable is indeed added but the
> predicate's condition doesn't constant fold.
>
> What happens is that the main loop's iv phi initial value is a CastII
> (added by PhaseIdealLoop::cast_incr_before_loop()). That CastII is
> input to the predicates above the main loop and of the main loop's iv
> phi. Once loop opts are over, the type of the CastII is updated by
> CastIINode::Value() (the logic that looks at the test that guards the
> CastII). The type update causes the main loop iv phi's type to be
> updated and a ConvI2L to be become top. The predicate that should
> catch the overunrolling has the shape:
>
> (CmpU (AddI#1 (CastII (AddI#2 (Phi ..) ConI#1)) ConI#2) ConI#3)
>
> In the case of the test case:
>
> ConI#3 = 10
> ConI#2 = 7
> ConI#1 = 1
>
> CastII has type = int:<=max-8
> Phi has type = int:>=8
>
> As a result:
> AddI#2 has type int
> AddI#1 has type int:min+7..max-1
>
> The Phi is the pre loop Phi.
>
> The fix I propose is that predicates when they are updated should skip
> over the CastII, that is in this case:
>
> (CmpU (AddI#1 (AddI#2 (Phi ..) ConI#1) ConI#2) ConI#3)
>
> which is reshaped to:
>
> (CmpU (AddI#1' (Phi ..) ConI#1') ConI#3)
>
> In this case:
>
> ConI#1 = 4 (because the predicate constant fold in earlier passes of
> unrolling)
>
> As a result AddI#1' still has type int But CmpUNode has special logic
> to deal with the (CmpU (AddI ...)) shape and it can determine that
> this one always fails.
>
> The role of the CastII is to enforce the dependency between nodes in
> the loop and the the loop entry test so it's not required for
> predicates.
>
> With that change, compiler/loopopts/TestOverunrolling.java fails
> because a predicate doesn't constant fold anymore. The reason in that
> case, is that PhaseIdealLoop::reorg_offsets() adds an Opaque2 between
> the pre loop iv phi and the predicate that hides the type of the iv
> phi. Without the change, the CastII captures the type of the iv phi
> and the Opaque2 node is added between the CastII and the pre loop iv
> phi. To solve that problem, I propose that
> PhaseIdealLoop::reorg_offsets() always add a CastII after the Opaque2
> so the type of the iv phi is not lost.
Gave this a quick run through testing and `compiler/c2/irTests/TestSkeletonPredicates.java` failed with `-XX:+CreateCoredumpOnCrash -ea -esa -XX:CompileThreshold=100 -XX:+UnlockExperimentalVMOptions -server -XX:-TieredCompilation`:
220 ConL === 0 [[ 221 ]] #long:8
218 ConL === 0 [[ 219 ]] #long:1
217 StoreP === 245 7 194 199 [[ 219 ]] @rawptr:BotPTR, idx=Raw; Memory: @rawptr:BotPTR, idx=Raw;
224 ConL === 0 [[ 225 ]] #long:12
250 ConNKlass === 0 [[ 223 ]] #narrowklass: precise [double: :Constant:exact *
221 AddP === _ 198 198 220 [[ 223 ]]
219 StoreL === 245 217 198 218 [[ 223 ]] @NULL Memory: @rawptr:BotPTR, idx=Raw;
195 ConL === 0 [[ 196 ]] #long:280
227 ConL === 0 [[ 232 ]] #long:16
225 AddP === _ 198 198 224 [[ 226 ]]
223 StoreNKlass === 245 219 221 250 [[ 226 ]] @NULL Memory: @rawptr:BotPTR, idx=Raw;
196 AddP === _ 1 192 195 [[ 197 ]]
232 AddP === _ 198 198 227 [[ 251 ]]
249 ConL === 0 [[ 251 ]] #long:10
226 StoreI === 245 223 225 24 [[ 251 ]] @NULL Memory: @rawptr:BotPTR, idx=Raw;
205 ConL === 0 [[ 206 ]] #long:192
197 LoadP === 5 7 196 [[ 200 ]] @rawptr:BotPTR, idx=Raw; #rawptr:BotPTR (does not depend only on test)
251 ClearArray === 245 226 249 232 [[ 189 ]] Memory: @rawptr:BotPTR, idx=Raw; !orig=[233]
208 ConL === 0 [[ 209 ]] #long:256
206 AddP === _ 198 199 205 [[ 207 ]]
200 CmpP === _ 199 197 [[ 242 ]]
140 CmpI === _ 125 30 [[ 141 ]] !jvms: TestSkeletonPredicates::test1 @ bci:22 (line 63)
189 Phi === 188 54 251 [[ 60 57 ]] #memory Memory: @rawptr:BotPTR, idx=Raw;
60 MergeMem === _ 1 189 1 1 1 7 [[ 57 ]] { - - - N7:double[int:>=0]:exact+any * } Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
38 ConL === 0 [[ 199 ]] #long:96
211 ConL === 0 [[ 212 ]] #long:320
209 AddP === _ 198 199 208 [[ 210 ]]
207 PrefetchAllocation === 245 6 206 [[ 210 ]]
242 Bool === _ 200 [[ 243 ]] [lt]
40 ConI === 0 [[ 181 ]] #int:1
141 Bool === _ 140 [[ 142 ]] [ne] !jvms: TestSkeletonPredicates::test1 @ bci:22 (line 63)
128 CatchProj === 127 [[ 142 ]] #0 at bci -1 !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
193 ConL === 0 [[ 194 ]] #long:264
192 ThreadLocal === 0 [[ 194 196 ]]
57 Initialize === 188 1 60 1 1 1 189 [[ 236 235 ]] !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
214 ConL === 0 [[ 215 ]] #long:384
199 AddP === _ 1 198 38 [[ 200 206 209 212 215 217 ]]
212 AddP === _ 198 199 211 [[ 213 ]]
210 PrefetchAllocation === _ 207 209 [[ 213 ]]
66 CmpI === _ 10 30 [[ 68 ]] !orig=64 !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
182 CmpI === _ 181 10 [[ 183 ]] !orig=[161] !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
115 Phi === 185 238 123 [[ 117 ]] #memory Memory: @double[int:>=0]:exact+any *, idx=6; !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
114 Phi === 185 238 123 [[ 117 ]] #memory Memory: @java/lang/Object+8 * [narrowklass], idx=5; !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
113 Phi === 185 238 123 [[ 117 ]] #memory Memory: @java/lang/Object *, idx=4; !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
112 Phi === 185 238 123 [[ 117 ]] #memory Memory: @rawptr:BotPTR, idx=Raw; !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
111 Phi === 185 7 123 [[ 117 ]] #memory Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
164 IfTrue === 184 [[ 185 ]] #1 !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
71 IfFalse === 69 [[ 185 ]] #0 !orig=[87],[100] !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
243 If === 5 242 [[ 244 245 ]] P=0.999900, C=-1.000000 !orig=[202]
181 AddI === _ 116 40 [[ 116 182 ]] !orig=[154] !jvms: TestSkeletonPredicates::test1 @ bci:27 (line 62)
30 ConI === 0 [[ 140 116 66 ]] #int:0
142 If === 128 141 [[ 143 144 ]] P=0.000000, C=12295.000000 !jvms: TestSkeletonPredicates::test1 @ bci:22 (line 63)
194 AddP === _ 1 192 193 [[ 198 217 ]]
5 Parm === 3 [[ 243 197 198 ]] Control !jvms: TestSkeletonPredicates::test1 @ bci:-1 (line 60)
236 Proj === 57 [[ 234 ]] #2 Memory: @rawptr:BotPTR, idx=Raw;
235 Proj === 57 [[ 234 ]] #0
215 AddP === _ 198 199 214 [[ 216 ]]
213 PrefetchAllocation === _ 210 212 [[ 216 ]]
245 IfTrue === 243 [[ 188 251 226 223 219 217 207 ]] #1 !orig=[204]
240 CatchProj === 48 [[ 188 ]] #0 at bci -1 !orig=[49] !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
68 Bool === _ 66 [[ 69 ]] [le] !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
183 Bool === _ 182 [[ 184 ]] [lt] !orig=[162] !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
144 IfFalse === 142 [[ 184 ]] #0 !orig=155 !jvms: TestSkeletonPredicates::test1 @ bci:22 (line 63)
119 ConI === 0 [[ 120 ]] #int:8
117 MergeMem === _ 1 111 112 113 114 115 [[ 120 ]] { N112:rawptr:BotPTR N113:java/lang/Object * N114:java/lang/Object+8 * [narrowklass] N115:double[int:>=0]:exact+any * } Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
110 Phi === 185 190 122 [[ 120 ]] #abIO !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
185 CountedLoop === 185 71 164 [[ 185 120 110 111 112 113 114 115 116 ]] inner stride: 1 !orig=[180],[109] !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
24 ConI === 0 [[ 239 226 ]] #int:10
25 ConP === 0 [[ 239 ]] #precise [double: :Constant:exact * Klass:precise [double: :Constant:exact *
244 IfFalse === 243 [[ 239 ]] #0 !orig=[203]
121 Proj === 120 [[ 127 ]] #0 !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
45 Proj === 239 [[ 48 ]] #0 !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
125 Proj === 120 [[ 149 140 ]] #5 !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
116 Phi === 185 30 181 [[ 120 181 149 120 ]] #int:>=0:www #tripcount !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
11 Parm === 3 [[ 149 120 120 239 ]] Parm1: double[int:>=0]:exact * !jvms: TestSkeletonPredicates::test1 @ bci:-1 (line 60)
10 Parm === 3 [[ 182 120 149 239 66 ]] Parm0: int !jvms: TestSkeletonPredicates::test1 @ bci:-1 (line 60)
148 ConI === 0 [[ 149 ]] #int:-187
143 IfTrue === 142 [[ 149 ]] #1 !jvms: TestSkeletonPredicates::test1 @ bci:22 (line 63)
198 LoadP === 5 7 194 [[ 199 206 209 212 215 219 221 221 225 225 232 232 191 ]] @rawptr:BotPTR, idx=Raw; #rawptr:BotPTR (does not depend only on test)
241 Proj === 239 [[ 191 ]] #5 !orig=[56] !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
234 MemBarStoreStore === 235 1 236 1 1 [[ 237 238 ]]
238 Proj === 234 [[ 170 171 172 173 112 113 114 115 ]] #2 Memory: @BotPTR *+bot, idx=Bot; !orig=[59],107 !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
216 PrefetchAllocation === _ 213 215 [[ 190 ]]
6 Parm === 3 [[ 207 190 ]] I_O !jvms: TestSkeletonPredicates::test1 @ bci:-1 (line 60)
188 Region === 188 240 245 [[ 188 189 190 191 57 ]] !orig=[49] !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
69 If === 237 68 [[ 70 71 ]] P=0.083352, C=13413.000000 !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
184 CountedLoopEnd === 144 183 [[ 165 164 ]] [lt] P=0.916648, C=12295.000000 !orig=[163] !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
54 Proj === 239 [[ 138 189 ]] #2 Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
123 Proj === 120 [[ 114 113 137 138 112 149 111 172 115 171 173 169 170 ]] #2 Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
7 Parm === 3 [[ 137 239 169 60 111 197 198 217 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !orig=[103] !jvms: TestSkeletonPredicates::test1 @ bci:-1 (line 60)
120 CallStaticJava === 185 110 117 8 1 ( 119 116 61 11 10 11 61 116 ) [[ 121 122 123 125 ]] # Static compiler.c2.irTests.TestSkeletonPredicates::test1_helper bool ( int, int, double[int:>=0]:exact *, double[int:>=0]:exact * ) TestSkeletonPredicates::test1 @ bci:19 (line 63) !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
239 CallStaticJava === 244 1 7 8 1 ( 25 24 10 11 1 1 ) [[ 241 55 54 45 ]] # Static _new_array_Java rawptr:NotNull ( java/lang/Object:NotNull *, int ) C=0.000100 TestSkeletonPredicates::test1 @ bci:4 (line 61) !orig=44 !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
127 Catch === 121 122 [[ 128 129 ]] !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
48 Catch === 45 55 [[ 240 50 ]] !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
149 CallStaticJava === 143 122 123 8 9 ( 148 10 11 61 116 125 ) [[ 150 ]] # Static uncommon_trap(reason='unstable_if' action='reinterpret' debug_id='0') void ( int ) C=0.000100 TestSkeletonPredicates::test1 @ bci:22 (line 63) reexecute !jvms: TestSkeletonPredicates::test1 @ bci:22 (line 63)
191 Phi === 188 241 198 [[ 61 ]] #rawptr:BotPTR !orig=[56] !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
237 Proj === 234 [[ 61 69 ]] #0 !orig=[58] !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
173 Phi === 74 123 238 [[ 17 ]] #memory Memory: @double[int:>=0]:exact+any *, idx=6; !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
172 Phi === 74 123 238 [[ 17 ]] #memory Memory: @java/lang/Object+8 * [narrowklass], idx=5; !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
171 Phi === 74 123 238 [[ 17 ]] #memory Memory: @java/lang/Object *, idx=4; !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
170 Phi === 74 123 238 [[ 17 ]] #memory Memory: @rawptr:BotPTR, idx=Raw; !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
169 Phi === 74 123 7 [[ 17 ]] #memory Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
190 Phi === 188 6 216 [[ 110 168 ]] #abIO
70 IfTrue === 69 [[ 74 ]] #1 !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
165 IfFalse === 184 [[ 74 ]] #0 !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
132 CreateEx === 129 122 [[ 139 ]] #java/lang/Throwable:NotNull * Oop:java/lang/Throwable:NotNull * !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
53 CreateEx === 50 55 [[ 139 ]] #java/lang/Throwable:NotNull * Oop:java/lang/Throwable:NotNull * !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
3 Start === 3 0 [[ 3 5 6 7 8 9 10 11 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:int, 6:double[int:>=0]:exact *}
138 Phi === 135 54 123 [[ 51 ]] #memory Memory: @rawptr:BotPTR, idx=Raw; !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
137 Phi === 135 7 123 [[ 51 ]] #memory Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
122 Proj === 120 [[ 149 127 136 132 168 110 ]] #1 !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
55 Proj === 239 [[ 48 53 136 ]] #1 !orig=102 !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
129 CatchProj === 127 [[ 135 132 ]] #1 at bci -1 !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
50 CatchProj === 48 [[ 135 53 ]] #1 at bci -1 !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
150 Proj === 149 [[ 153 ]] #0 !jvms: TestSkeletonPredicates::test1 @ bci:22 (line 63)
61 CheckCastPP === 237 191 [[ 178 120 120 149 ]] #double[int:10]:NotNull:exact * !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
17 MergeMem === _ 1 169 170 171 172 173 [[ 178 ]] { N170:rawptr:BotPTR N171:java/lang/Object * N172:java/lang/Object+8 * [narrowklass] N173:double[int:>=0]:exact+any * } Memory: @BotPTR *+bot, idx=Bot;
168 Phi === 74 122 190 [[ 178 ]] #abIO !jvms: TestSkeletonPredicates::test1 @ bci:11 (line 62)
74 Region === 74 165 70 [[ 74 178 168 169 170 171 172 173 ]] !jvms: TestSkeletonPredicates::test1 @ bci:33 (line 67)
139 Phi === 135 53 132 [[ 179 ]] #java/lang/Throwable:NotNull * Oop:java/lang/Throwable:NotNull * !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
9 Parm === 3 [[ 179 178 149 ]] ReturnAdr !jvms: TestSkeletonPredicates::test1 @ bci:-1 (line 60)
8 Parm === 3 [[ 179 178 149 120 239 153 ]] FramePtr !jvms: TestSkeletonPredicates::test1 @ bci:-1 (line 60)
51 MergeMem === _ 1 137 138 [[ 179 ]] { N138:rawptr:BotPTR } Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSkeletonPredicates::test1 @ bci:4 (line 61)
136 Phi === 135 55 122 [[ 179 ]] #abIO !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
135 Region === 135 50 129 [[ 135 136 137 138 139 179 ]] !jvms: TestSkeletonPredicates::test1 @ bci:19 (line 63)
153 Halt === 150 1 1 8 1 [[ 0 ]] !jvms: TestSkeletonPredicates::test1 @ bci:22 (line 63)
178 Return === 74 168 17 8 9 returns 61 [[ 0 ]]
179 Rethrow === 135 136 51 8 9 exception 139 [[ 0 ]]
0 Root === 0 179 178 153 [[ 0 1 3 38 24 25 148 158 30 119 94 81 40 186 187 192 193 195 205 208 211 214 218 220 224 227 228 246 247 249 250 ]]
[...]
1) Method "static double[] compiler.c2.irTests.TestSkeletonPredicates.test1(int,double[])" - [Failed IR rules: 1]:
* @IR rule 1: "@compiler.lib.ir_framework.IR(applyIf={}, applyIfAnd={}, failOn={}, applyIfOr={}, counts={"(\\\\d+(\\\\s){2}(CountedLoop\\\\b.*)+(\\\\s){2}===.*)", "3"}, applyIfNot={})"
- counts: Graph contains wrong number of nodes:
* Regex 1: (\\d+(\\s){2}(CountedLoop\\b.*)+(\\s){2}===.*)
- Failed comparison: [found] 1 = 3 [given]
- Matched node:
* 185 CountedLoop === 185 71 164 [[ 185 120 110 111 112 113 114 115 116 ]] inner stride: 1 !orig=[180],[109] !jvms: TestSkeletonPredicates::test1 @ bci:14 (line 63)
-------------
PR: https://git.openjdk.java.net/jdk/pull/7758
More information about the hotspot-compiler-dev
mailing list