|
|
|
|
|
by kleendr13
2065 days ago
|
|
Very interesting question, I just gave that a run with i and j being unknown and seems it's getting rejected by the verifier as it still probes the else path. Note that LLVM will convert the xor patterns to moves: ; __u64 i = PT_REGS_FP(ctx), j = PT_REGS_RC(ctx);
0: (79) r2 = *(u64 *)(r1 +32)
; __u64 i = PT_REGS_FP(ctx), j = PT_REGS_RC(ctx);
1: (79) r1 = *(u64 *)(r1 +80)
;
2: (bf) r3 = r1
3: (bf) r1 = r2
4: (bf) r2 = r3
; if (i <= j) { return 0; }
5: (2d) if r3 > r1 goto pc-4
from 5 to 2: R1=inv(id=2) R2=inv(id=1) R3=inv(id=1) R10=fp0
;
2: (bf) r3 = r1
3: (bf) r1 = r2
4: (bf) r2 = r3
; if (i <= j) { return 0; }
5: (2d) if r3 > r1 goto pc-4
from 5 to 2: R1_w=inv(id=1) R2_w=inv(id=2) R3_w=inv(id=2) R10=fp0
;
2: (bf) r3 = r1
3: (bf) r1 = r2
4: (bf) r2 = r3
; if (i <= j) { return 0; }
5: (2d) if r3 > r1 goto pc-4
;
infinite loop detected at insn 2
|
|
1. If the answer is no, then what is the precise reason? Is there a legitimate reason for it? After all, a bounded loop that loops for too long is just as bad as one that never terminates, so clearly they need a way to upper-bound the instruction count for any loop—at which point, why is the bound even relevant? The only reason I can think of is that they do simplistic analysis (e.g. multiplying the bounds on nested loops to naively approximate an overall bound), but your examples suggest they have more sophisticated (SMT/BMC?) solvers, and it's not obvious to me why a modern solver would fail on all unbounded loops.
2. If the answer is yes, then it would seem they actually do allow unbounded loops after all?
The other possibility is they're using the word "bounded" differently (e.g. maybe as a synonym for "terminating"), in which case it would be true that they would need bounded loops by definition.