aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/Expr/Expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Expr/Expr.cpp')
-rw-r--r--lib/Expr/Expr.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/Expr/Expr.cpp b/lib/Expr/Expr.cpp
index 15f52184..ac50dda2 100644
--- a/lib/Expr/Expr.cpp
+++ b/lib/Expr/Expr.cpp
@@ -529,6 +529,7 @@ ref<Expr> ReadExpr::create(const UpdateList &ul, ref<Expr> index) {
// a smart UpdateList so it is not worth rescanning.
const UpdateNode *un = ul.head;
+ bool updateListHasSymbolicWrites = false;
for (; un; un=un->next) {
ref<Expr> cond = EqExpr::create(index, un->index);
@@ -536,10 +537,22 @@ ref<Expr> ReadExpr::create(const UpdateList &ul, ref<Expr> index) {
if (CE->isTrue())
return un->value;
} else {
+ updateListHasSymbolicWrites = true;
break;
}
}
+ if (ul.root->isConstantArray() && !updateListHasSymbolicWrites) {
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(index)) {
+ assert(CE->getWidth() <= 64 && "Index too large");
+ uint64_t concreteIndex = CE->getZExtValue();
+ uint64_t size = ul.root->size;
+ if (concreteIndex < size) {
+ return ul.root->constantValues[concreteIndex];
+ }
+ }
+ }
+
return ReadExpr::alloc(ul, index);
}