@@ -1132,6 +1132,47 @@ module RangeStage<
11321132 bindingset [ x, y]
11331133 private float truncatingDiv ( float x , float y ) { result = ( x - ( x % y ) ) / y }
11341134
1135+ /**
1136+ * Holds if `e1 + delta` is a valid bound for `e2`.
1137+ * - `upper = true` : `e2 <= e1 + delta`
1138+ * - `upper = false` : `e2 >= e1 + delta`
1139+ *
1140+ * This is restricted to simple forward-flowing steps and disregards phi-nodes.
1141+ */
1142+ private predicate preBoundStep ( Sem:: Expr e2 , Sem:: Expr e1 , D:: Delta delta , boolean upper ) {
1143+ boundFlowStep ( e2 , e1 , delta , upper )
1144+ or
1145+ exists ( Sem:: SsaVariable v , SsaReadPositionBlock bb |
1146+ boundFlowStepSsa ( v , bb , e1 , delta , upper , _) and
1147+ bb .getAnSsaRead ( v ) = e2
1148+ )
1149+ }
1150+
1151+ /**
1152+ * Holds if simple forward-flowing steps from `e` can reach an expression that
1153+ * has multiple incoming bound-flow edges, that is, it has multiple ways to
1154+ * get a valid bound.
1155+ */
1156+ private predicate reachesBoundMergepoint ( Sem:: Expr e , boolean upper ) {
1157+ 2 <= strictcount ( Sem:: Expr mid | preBoundStep ( e , mid , _, upper ) )
1158+ or
1159+ exists ( Sem:: SsaPhiNode v , SsaReadPositionBlock bb |
1160+ boundFlowStepSsa ( v , bb , _, _, upper , _) and
1161+ bb .getAnSsaRead ( v ) = e
1162+ )
1163+ or
1164+ exists ( Sem:: Expr e2 |
1165+ preBoundStep ( e2 , e , _, upper ) and
1166+ reachesBoundMergepoint ( e2 , upper )
1167+ )
1168+ }
1169+
1170+ pragma [ nomagic]
1171+ private predicate relevantPreBoundStep ( Sem:: Expr e2 , Sem:: Expr e1 , D:: Delta delta , boolean upper ) {
1172+ preBoundStep ( e2 , e1 , delta , upper ) and
1173+ reachesBoundMergepoint ( e2 , upper )
1174+ }
1175+
11351176 /**
11361177 * Holds if `b + delta` is a valid bound for `e` that can be found using only
11371178 * simple forward-flowing steps and disregarding phi-nodes.
@@ -1155,17 +1196,10 @@ module RangeStage<
11551196 baseBound ( e , b , delta , upper )
11561197 or
11571198 exists ( Sem:: Expr mid , D:: Delta d1 , D:: Delta d2 |
1158- boundFlowStep ( e , mid , d1 , upper ) and
1199+ relevantPreBoundStep ( e , mid , d1 , upper ) and
11591200 preBounded ( mid , b , d2 , upper ) and
11601201 delta = D:: fromFloat ( D:: toFloat ( d1 ) + D:: toFloat ( d2 ) )
11611202 )
1162- or
1163- exists ( Sem:: SsaVariable v , SsaReadPositionBlock bb , Sem:: Expr mid , D:: Delta d1 , D:: Delta d2 |
1164- boundFlowStepSsa ( v , bb , mid , d1 , upper , _) and
1165- preBounded ( mid , b , d2 , upper ) and
1166- delta = D:: fromFloat ( D:: toFloat ( d1 ) + D:: toFloat ( d2 ) ) and
1167- bb .getAnSsaRead ( v ) = e
1168- )
11691203 }
11701204
11711205 private predicate bestPreBound ( Sem:: Expr e , SemBound b , D:: Delta delta , boolean upper ) {
0 commit comments