@@ -154,7 +154,16 @@ let constBefore var loop f =
154
154
let targetLocation = loopLocation loop
155
155
in let rec lastAssignmentToVarBeforeLoop (current : (Z.t option) ) (statements : stmt list ) = match statements with
156
156
| st ::stmts -> (
157
- let current' = if st.labels <> [] then (Logs. debug " has Label" ; (None )) else current in
157
+ let current' =
158
+ (* If there exists labels that are not the ones inserted by loop unrolling, forget the found assigned constant value *)
159
+ if List. exists (function
160
+ | Label (s ,_ ,_ ) -> not (String. starts_with ~prefix: " loop_continue" s || String. starts_with ~prefix: " loop_end" s)
161
+ | _ -> true ) st.labels
162
+ then
163
+ (Logs. debug " has Label" ; (None ))
164
+ else
165
+ current
166
+ in
158
167
match st.skind with
159
168
| Instr list -> (
160
169
match lastAssignToVar var list with
@@ -220,13 +229,21 @@ let findBreakComparison loopStatement =
220
229
with WrongOrMultiple ->
221
230
None
222
231
223
- let getLoopVar = function
232
+ let getLoopVar loopStatement func = function
224
233
| BinOp (op , (Const (CInt (goal , _ , _ ) )), Lval ((Var varinfo ), NoOffset), (TInt _ )) when isCompare op && not varinfo.vglob ->
225
234
(* TODO: define isCompare and flip in cilfacade and refactor to use instead of the many separately defined similar functions *)
226
235
let flip = function | Lt -> Gt | Gt -> Lt | Ge -> Le | Le -> Ge | s -> s in
227
236
Some (flip op, varinfo, goal)
228
237
| BinOp (op , Lval ((Var varinfo ), NoOffset), (Const (CInt (goal , _ , _ ) )), (TInt _ )) when isCompare op && not varinfo.vglob ->
229
238
Some (op, varinfo, goal)
239
+ (* When loop condition has a comparison between variables, we assume that the left one is the counter and right one is the bound.
240
+ TODO: can we do something more meaningful instead of this assumption? *)
241
+ | BinOp (op, Lval ((Var varinfo), NoOffset ), Lval ((Var varinfo2), NoOffset ), (TInt _))
242
+ | BinOp (op , CastE ((TInt _ ), (Lval ((Var varinfo ), NoOffset))), Lval ((Var varinfo2 ), NoOffset), (TInt _ )) when isCompare op && not varinfo.vglob && not varinfo2.vglob ->
243
+ begin match constBefore varinfo2 loopStatement func with
244
+ | Some goal -> Logs. debug " const: %a %a" CilType.Varinfo. pretty varinfo2 GobZ. pretty goal; Some (op, varinfo, goal)
245
+ | None -> None
246
+ end ;
230
247
| _ -> None
231
248
232
249
let getsPointedAt var func =
@@ -273,7 +290,7 @@ let loopIterations start diff goal shouldBeExact =
273
290
let fixedLoopSize loopStatement func =
274
291
let open GobOption.Syntax in
275
292
let * comparison = findBreakComparison loopStatement in
276
- let * op, var, goal = getLoopVar comparison in
293
+ let * op, var, goal = getLoopVar loopStatement func comparison in
277
294
if getsPointedAt var func then
278
295
None
279
296
else
0 commit comments