summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2016-12-22 15:15:10 +0000
committerDan Gohman <dan433584@gmail.com>2016-12-22 15:15:10 +0000
commit728926ac59a8988468cb74181083f32c7f6951ed (patch)
tree2b836fbb3432b48194c263d86c84589b1490b135 /llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
parent0e0a8b4d85691d23777af21db48e2358bdcf5e79 (diff)
downloadbcm5719-llvm-728926ac59a8988468cb74181083f32c7f6951ed.tar.gz
bcm5719-llvm-728926ac59a8988468cb74181083f32c7f6951ed.zip
[WebAssembly] Don't old negative load/store offsets in fast-isel.
WebAssembly's load/store offsets are unsigned and don't wrap, so it's not valid to fold in a negative offset. llvm-svn: 290342
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp33
1 files changed, 24 insertions, 9 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 4bdf06aaaf9..529540ea4ed 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -84,7 +84,10 @@ class WebAssemblyFastISel final : public FastISel {
return Base.FI;
}
- void setOffset(int64_t Offset_) { Offset = Offset_; }
+ void setOffset(int64_t Offset_) {
+ assert(Offset_ >= 0 && "Offsets must be non-negative");
+ Offset = Offset_;
+ }
int64_t getOffset() const { return Offset; }
void setGlobalValue(const GlobalValue *G) { GV = G; }
const GlobalValue *getGlobalValue() const { return GV; }
@@ -236,6 +239,9 @@ bool WebAssemblyFastISel::computeAddress(const Value *Obj, Address &Addr) {
case Instruction::GetElementPtr: {
Address SavedAddr = Addr;
uint64_t TmpOffset = Addr.getOffset();
+ // Non-inbounds geps can wrap; wasm's offsets can't.
+ if (!cast<GEPOperator>(U)->isInBounds())
+ goto unsupported_gep;
// Iterate through the GEP folding the constants into offsets where
// we can.
for (gep_type_iterator GTI = gep_type_begin(U), E = gep_type_end(U);
@@ -272,10 +278,13 @@ bool WebAssemblyFastISel::computeAddress(const Value *Obj, Address &Addr) {
}
}
}
- // Try to grab the base operand now.
- Addr.setOffset(TmpOffset);
- if (computeAddress(U->getOperand(0), Addr))
- return true;
+ // Don't fold in negative offsets.
+ if (int64_t(TmpOffset) >= 0) {
+ // Try to grab the base operand now.
+ Addr.setOffset(TmpOffset);
+ if (computeAddress(U->getOperand(0), Addr))
+ return true;
+ }
// We failed, restore everything and try the other options.
Addr = SavedAddr;
unsupported_gep:
@@ -301,8 +310,11 @@ bool WebAssemblyFastISel::computeAddress(const Value *Obj, Address &Addr) {
std::swap(LHS, RHS);
if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
- Addr.setOffset(Addr.getOffset() + CI->getSExtValue());
- return computeAddress(LHS, Addr);
+ uint64_t TmpOffset = Addr.getOffset() + CI->getSExtValue();
+ if (int64_t(TmpOffset) >= 0) {
+ Addr.setOffset(TmpOffset);
+ return computeAddress(LHS, Addr);
+ }
}
Address Backup = Addr;
@@ -318,8 +330,11 @@ bool WebAssemblyFastISel::computeAddress(const Value *Obj, Address &Addr) {
const Value *RHS = U->getOperand(1);
if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
- Addr.setOffset(Addr.getOffset() - CI->getSExtValue());
- return computeAddress(LHS, Addr);
+ int64_t TmpOffset = Addr.getOffset() - CI->getSExtValue();
+ if (TmpOffset >= 0) {
+ Addr.setOffset(TmpOffset);
+ return computeAddress(LHS, Addr);
+ }
}
break;
}
OpenPOWER on IntegriCloud