|
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