@@ -80,7 +80,7 @@ private module RangeAnalysisCache {
8080 cached
8181 module RangeAnalysisPublic {
8282 /**
83- * Holds if `b + delta` is a valid bound for `i`.
83+ * Holds if `b + delta` is a valid bound for `i` and this is the best such delta .
8484 * - `upper = true` : `i <= b + delta`
8585 * - `upper = false` : `i >= b + delta`
8686 *
@@ -90,11 +90,12 @@ private module RangeAnalysisCache {
9090 */
9191 cached
9292 predicate boundedInstruction ( Instruction i , Bound b , int delta , boolean upper , Reason reason ) {
93- boundedInstruction ( i , b , delta , upper , _, _, reason )
93+ boundedInstruction ( i , b , delta , upper , _, _, reason ) and
94+ bestInstructionBound ( i , b , delta , upper )
9495 }
9596
9697 /**
97- * Holds if `b + delta` is a valid bound for `op`.
98+ * Holds if `b + delta` is a valid bound for `op` and this is the best such delta .
9899 * - `upper = true` : `op <= b + delta`
99100 * - `upper = false` : `op >= b + delta`
100101 *
@@ -104,9 +105,8 @@ private module RangeAnalysisCache {
104105 */
105106 cached
106107 predicate boundedOperand ( Operand op , Bound b , int delta , boolean upper , Reason reason ) {
107- boundedNonPhiOperand ( op , b , delta , upper , _, _, reason )
108- or
109- boundedPhiOperand ( op , b , delta , upper , _, _, reason )
108+ boundedOperandCand ( op , b , delta , upper , reason ) and
109+ bestOperandBound ( op , b , delta , upper )
110110 }
111111 }
112112
@@ -124,6 +124,43 @@ private module RangeAnalysisCache {
124124private import RangeAnalysisCache
125125import RangeAnalysisPublic
126126
127+ /**
128+ * Holds if `b + delta` is a valid bound for `e` and this is the best such delta.
129+ * - `upper = true` : `e <= b + delta`
130+ * - `upper = false` : `e >= b + delta`
131+ */
132+ private predicate bestInstructionBound ( Instruction i , Bound b , int delta , boolean upper ) {
133+ delta = min ( int d | boundedInstruction ( i , b , d , upper , _, _, _) ) and upper = true
134+ or
135+ delta = max ( int d | boundedInstruction ( i , b , d , upper , _, _, _) ) and upper = false
136+ }
137+
138+ /**
139+ * Holds if `b + delta` is a valid bound for `op`.
140+ * - `upper = true` : `op <= b + delta`
141+ * - `upper = false` : `op >= b + delta`
142+ *
143+ * The reason for the bound is given by `reason` and may be either a condition
144+ * or `NoReason` if the bound was proven directly without the use of a bounding
145+ * condition.
146+ */
147+ private predicate boundedOperandCand ( Operand op , Bound b , int delta , boolean upper , Reason reason ) {
148+ boundedNonPhiOperand ( op , b , delta , upper , _, _, reason )
149+ or
150+ boundedPhiOperand ( op , b , delta , upper , _, _, reason )
151+ }
152+
153+ /**
154+ * Holds if `b + delta` is a valid bound for `op` and this is the best such delta.
155+ * - `upper = true` : `op <= b + delta`
156+ * - `upper = false` : `op >= b + delta`
157+ */
158+ private predicate bestOperandBound ( Operand op , Bound b , int delta , boolean upper ) {
159+ delta = min ( int d | boundedOperandCand ( op , b , d , upper , _) ) and upper = true
160+ or
161+ delta = max ( int d | boundedOperandCand ( op , b , d , upper , _) ) and upper = false
162+ }
163+
127164/**
128165 * Gets a condition that tests whether `vn` equals `bound + delta`.
129166 *
0 commit comments