@@ -1132,6 +1132,47 @@ module RangeStage<
1132
1132
bindingset [ x, y]
1133
1133
private float truncatingDiv ( float x , float y ) { result = ( x - ( x % y ) ) / y }
1134
1134
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
+
1135
1176
/**
1136
1177
* Holds if `b + delta` is a valid bound for `e` that can be found using only
1137
1178
* simple forward-flowing steps and disregarding phi-nodes.
@@ -1155,17 +1196,10 @@ module RangeStage<
1155
1196
baseBound ( e , b , delta , upper )
1156
1197
or
1157
1198
exists ( Sem:: Expr mid , D:: Delta d1 , D:: Delta d2 |
1158
- boundFlowStep ( e , mid , d1 , upper ) and
1199
+ relevantPreBoundStep ( e , mid , d1 , upper ) and
1159
1200
preBounded ( mid , b , d2 , upper ) and
1160
1201
delta = D:: fromFloat ( D:: toFloat ( d1 ) + D:: toFloat ( d2 ) )
1161
1202
)
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
- )
1169
1203
}
1170
1204
1171
1205
private predicate bestPreBound ( Sem:: Expr e , SemBound b , D:: Delta delta , boolean upper ) {
0 commit comments