|
20 | 20 | #include "llvm/ADT/FoldingSet.h"
|
21 | 21 | #include "llvm/ADT/ImmutableSet.h"
|
22 | 22 | #include "llvm/ADT/STLExtras.h"
|
23 |
| -#include "llvm/ADT/StringExtras.h" |
24 | 23 | #include "llvm/ADT/SmallSet.h"
|
| 24 | +#include "llvm/ADT/StringExtras.h" |
25 | 25 | #include "llvm/Support/Compiler.h"
|
26 | 26 | #include "llvm/Support/raw_ostream.h"
|
27 | 27 | #include <algorithm>
|
@@ -955,18 +955,7 @@ class SymbolicRangeInferrer
|
955 | 955 | }
|
956 | 956 |
|
957 | 957 | RangeSet VisitBinaryOperator(RangeSet LHS, BinaryOperator::Opcode Op,
|
958 |
| - RangeSet RHS, QualType T) { |
959 |
| - switch (Op) { |
960 |
| - case BO_Or: |
961 |
| - return VisitBinaryOperator<BO_Or>(LHS, RHS, T); |
962 |
| - case BO_And: |
963 |
| - return VisitBinaryOperator<BO_And>(LHS, RHS, T); |
964 |
| - case BO_Rem: |
965 |
| - return VisitBinaryOperator<BO_Rem>(LHS, RHS, T); |
966 |
| - default: |
967 |
| - return infer(T); |
968 |
| - } |
969 |
| - } |
| 958 | + RangeSet RHS, QualType T); |
970 | 959 |
|
971 | 960 | //===----------------------------------------------------------------------===//
|
972 | 961 | // Ranges and operators
|
@@ -1231,6 +1220,29 @@ class SymbolicRangeInferrer
|
1231 | 1220 | // Range-based reasoning about symbolic operations
|
1232 | 1221 | //===----------------------------------------------------------------------===//
|
1233 | 1222 |
|
| 1223 | +template <> |
| 1224 | +RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_NE>(RangeSet LHS, |
| 1225 | + RangeSet RHS, |
| 1226 | + QualType T) { |
| 1227 | + // When both the RangeSets are non-overlapping then all possible pairs of |
| 1228 | + // (x, y) in LHS, RHS respectively, will satisfy expression (x != y). |
| 1229 | + if ((LHS.getMaxValue() < RHS.getMinValue()) || |
| 1230 | + (LHS.getMinValue() > RHS.getMaxValue())) { |
| 1231 | + return getTrueRange(T); |
| 1232 | + } |
| 1233 | + |
| 1234 | + // If both RangeSets contain only one Point which is equal then the |
| 1235 | + // expression will always return true. |
| 1236 | + if ((LHS.getMinValue() == RHS.getMaxValue()) && |
| 1237 | + (LHS.getMaxValue() == RHS.getMaxValue()) && |
| 1238 | + (LHS.getMinValue() == RHS.getMinValue())) { |
| 1239 | + return getFalseRange(T); |
| 1240 | + } |
| 1241 | + |
| 1242 | + // In all other cases, the resulting range cannot be deduced. |
| 1243 | + return infer(T); |
| 1244 | +} |
| 1245 | + |
1234 | 1246 | template <>
|
1235 | 1247 | RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_Or>(Range LHS, Range RHS,
|
1236 | 1248 | QualType T) {
|
@@ -1391,6 +1403,23 @@ RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_Rem>(Range LHS,
|
1391 | 1403 | return {RangeFactory, ValueFactory.getValue(Min), ValueFactory.getValue(Max)};
|
1392 | 1404 | }
|
1393 | 1405 |
|
| 1406 | +RangeSet SymbolicRangeInferrer::VisitBinaryOperator(RangeSet LHS, |
| 1407 | + BinaryOperator::Opcode Op, |
| 1408 | + RangeSet RHS, QualType T) { |
| 1409 | + switch (Op) { |
| 1410 | + case BO_NE: |
| 1411 | + return VisitBinaryOperator<BO_NE>(LHS, RHS, T); |
| 1412 | + case BO_Or: |
| 1413 | + return VisitBinaryOperator<BO_Or>(LHS, RHS, T); |
| 1414 | + case BO_And: |
| 1415 | + return VisitBinaryOperator<BO_And>(LHS, RHS, T); |
| 1416 | + case BO_Rem: |
| 1417 | + return VisitBinaryOperator<BO_Rem>(LHS, RHS, T); |
| 1418 | + default: |
| 1419 | + return infer(T); |
| 1420 | + } |
| 1421 | +} |
| 1422 | + |
1394 | 1423 | //===----------------------------------------------------------------------===//
|
1395 | 1424 | // Constraint manager implementation details
|
1396 | 1425 | //===----------------------------------------------------------------------===//
|
|
0 commit comments