You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[BoundsSafety] Optimize BS_CHK_AccessSize for the case element type is 1 byte
Previously for something like
```
T* __bidi_indexable ptr;
ptr[idx];
```
for the upper bound check (when BS_CHK_AccessSize is active) we always checked
1. `&ptr[idx] + sizeof(T)` does not overflow
2. `&ptr[idx] + sizeof(T) <= ptr.upper_bound`
However, for the case `sizeof(T) == 1` we can actually just check
`&ptr[idx] < ptr.upper_bound`
and completely avoid performing the overflow check. This gives us
a code size and runtime overhead win in this particular case.
We can use Z3 to prove the two different bounds checks implementations
are identical when the access size is 1 using the SMT-LIBv2 file shown below:
```
(set-logic QF_BV)
(declare-const cur (_ BitVec 64))
(declare-const upper (_ BitVec 64))
(declare-const access_size (_ BitVec 64))
;;; for inspecting model
(declare-const overflows Bool)
(declare-const cur_plus_access_size (_ BitVec 64))
(define-fun add_overflows ((a (_ BitVec 64)) (b (_ BitVec 64))) Bool
(bvult
(bvadd a b)
a
)
)
;;; Access size is not zero
(assert
(not (= access_size #x0000000000000000))
)
;;; `overflows` is a convenience variable for inspecting the model
(assert
(=
overflows
(add_overflows cur access_size)
)
)
;;; `cur_plus_access_size` is a convenience variable for inspecting the model
(assert
(=
cur_plus_access_size
(bvadd cur access_size)
)
)
;;; Consider the special case with access size of 1
(assert
(= access_size #x0000000000000001)
)
;;;; New upper bound check semantics
(define-fun new_in_bounds () Bool
(and
(not (add_overflows cur access_size))
(bvule
(bvadd cur access_size)
upper
)
)
)
;;;; Old upper bound check semantics
(define-fun old_in_bounds () Bool
(and
(bvult
cur
upper
)
)
)
(assert
(not
(=
new_in_bounds
old_in_bounds
)
)
)
(check-sat); reports unsat
(get-model)
(get-value (old_in_bounds))
(get-value (new_in_bounds))
(get-value (cur_plus_access_size))
(get-value (overflows))
```
rdar://139665133
(cherry picked from commit 84b0262)
Conflicts:
clang/test/BoundsSafety/CodeGen/range-check-optimizations.c
0 commit comments