@@ -1062,6 +1062,20 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
1062
1062
or
1063
1063
upper = false and delta = D:: fromFloat ( - D:: toFloat ( d_max ) .abs ( ) + 1 )
1064
1064
)
1065
+ or
1066
+ exists (
1067
+ SemZeroBound bLeft , SemZeroBound bRight , D:: Delta dLeft , D:: Delta dRight , boolean fbeLeft ,
1068
+ boolean fbeRight , D:: Delta odLeft , D:: Delta odRight , SemReason rLeft , SemReason rRight
1069
+ |
1070
+ boundedMulOperand ( e , upper , bLeft , true , dLeft , fbeLeft , odLeft , rLeft ) and
1071
+ boundedMulOperand ( e , upper , bRight , false , dRight , fbeRight , odRight , rRight ) and
1072
+ delta = D:: fromFloat ( D:: toFloat ( dLeft ) * D:: toFloat ( dRight ) ) and
1073
+ fromBackEdge = fbeLeft .booleanOr ( fbeRight )
1074
+ |
1075
+ b = bLeft and origdelta = odLeft and reason = rLeft
1076
+ or
1077
+ b = bRight and origdelta = odRight and reason = rRight
1078
+ )
1065
1079
)
1066
1080
}
1067
1081
@@ -1095,4 +1109,100 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
1095
1109
) {
1096
1110
bounded ( rem .getRightOperand ( ) , b , delta , upper , fromBackEdge , origdelta , reason )
1097
1111
}
1112
+
1113
+ /**
1114
+ * Define `cmp(true) = <=` and `cmp(false) >=`.
1115
+ *
1116
+ * Holds if `mul = left * right`, and in order to know if `mul cmp(upper) B + k` (for
1117
+ * some `B` and `k`) we need to know that `left cmp(upperLeft) B1 + k1` and
1118
+ * `right cmp(upperRight) B2 + k2` (for some `B1`, `B2`, `k1`, and `k2`).
1119
+ */
1120
+ pragma [ nomagic]
1121
+ private predicate boundedMulOperandCand (
1122
+ SemMulExpr mul , SemExpr left , SemExpr right , boolean upper , boolean upperLeft ,
1123
+ boolean upperRight
1124
+ ) {
1125
+ not boundFlowStepMul ( mul , _, _) and
1126
+ mul .getLeftOperand ( ) = left and
1127
+ mul .getRightOperand ( ) = right and
1128
+ (
1129
+ semPositive ( left ) and
1130
+ (
1131
+ // left, right >= 0
1132
+ semPositive ( right ) and
1133
+ (
1134
+ // max(left * right) = max(left) * max(right)
1135
+ upper = true and
1136
+ upperLeft = true and
1137
+ upperRight = true
1138
+ or
1139
+ // min(left * right) = min(left) * min(right)
1140
+ upper = false and
1141
+ upperLeft = false and
1142
+ upperRight = false
1143
+ )
1144
+ or
1145
+ // left >= 0, right <= 0
1146
+ semNegative ( right ) and
1147
+ (
1148
+ // max(left * right) = min(left) * max(right)
1149
+ upper = true and
1150
+ upperLeft = false and
1151
+ upperRight = true
1152
+ or
1153
+ // min(left * right) = max(left) * min(right)
1154
+ upper = false and
1155
+ upperLeft = true and
1156
+ upperRight = false
1157
+ )
1158
+ )
1159
+ or
1160
+ semNegative ( left ) and
1161
+ (
1162
+ // left <= 0, right >= 0
1163
+ semPositive ( right ) and
1164
+ (
1165
+ // max(left * right) = max(left) * min(right)
1166
+ upper = true and
1167
+ upperLeft = true and
1168
+ upperRight = false
1169
+ or
1170
+ // min(left * right) = min(left) * max(right)
1171
+ upper = false and
1172
+ upperLeft = false and
1173
+ upperRight = true
1174
+ )
1175
+ or
1176
+ // left, right <= 0
1177
+ semNegative ( right ) and
1178
+ (
1179
+ // max(left * right) = min(left) * min(right)
1180
+ upper = true and
1181
+ upperLeft = false and
1182
+ upperRight = false
1183
+ or
1184
+ // min(left * right) = max(left) * max(right)
1185
+ upper = false and
1186
+ upperLeft = true and
1187
+ upperRight = true
1188
+ )
1189
+ )
1190
+ )
1191
+ }
1192
+
1193
+ pragma [ nomagic]
1194
+ private predicate boundedMulOperand (
1195
+ SemMulExpr mul , boolean upper , SemZeroBound b , boolean isLeft , D:: Delta delta ,
1196
+ boolean fromBackEdge , D:: Delta origdelta , SemReason reason
1197
+ ) {
1198
+ exists ( boolean upperLeft , boolean upperRight , SemExpr left , SemExpr right |
1199
+ boundedMulOperandCand ( mul , left , right , upper , upperLeft , upperRight )
1200
+ |
1201
+ isLeft = true and
1202
+ bounded ( left , b , delta , upperLeft , fromBackEdge , origdelta , reason )
1203
+ or
1204
+ isLeft = false and
1205
+ bounded ( right , b , delta , upperRight , fromBackEdge , origdelta , reason )
1206
+ )
1207
+ }
1098
1208
}
0 commit comments