[llvm] r290342 - [WebAssembly] Don't old negative load/store offsets in fast-isel.
Dan Gohman via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 22 07:15:10 PST 2016
Author: djg
Date: Thu Dec 22 09:15:10 2016
New Revision: 290342
URL: http://llvm.org/viewvc/llvm-project?rev=290342&view=rev
Log:
[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.
Modified:
llvm/trunk/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
llvm/trunk/test/CodeGen/WebAssembly/fast-isel.ll
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyFastISel.cpp?rev=290342&r1=290341&r2=290342&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyFastISel.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyFastISel.cpp Thu Dec 22 09:15:10 2016
@@ -84,7 +84,10 @@ class WebAssemblyFastISel final : public
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
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
}
}
}
- // 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
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 *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;
}
Modified: llvm/trunk/test/CodeGen/WebAssembly/fast-isel.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/fast-isel.ll?rev=290342&r1=290341&r2=290342&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/fast-isel.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/fast-isel.ll Thu Dec 22 09:15:10 2016
@@ -46,3 +46,33 @@ define double @bitcast_f64_i64(i64 %x) {
%y = bitcast i64 %x to double
ret double %y
}
+
+; Do fold offsets into geps.
+; CHECK-LABEL: do_fold_offset_into_gep:
+; CHECK: i64.load $push{{[0-9]+}}=, 8($0)
+define i64 @do_fold_offset_into_gep(i64* %p) {
+bb:
+ %tmp = getelementptr inbounds i64, i64* %p, i32 1
+ %tmp2 = load i64, i64* %tmp, align 8
+ ret i64 %tmp2
+}
+
+; Don't fold negative offsets into geps.
+; CHECK-LABEL: dont_fold_negative_offset:
+; CHECK: i64.load $push{{[0-9]+}}=, 0($pop{{[0-9]+}})
+define i64 @dont_fold_negative_offset(i64* %p) {
+bb:
+ %tmp = getelementptr inbounds i64, i64* %p, i32 -1
+ %tmp2 = load i64, i64* %tmp, align 8
+ ret i64 %tmp2
+}
+
+; Don't fold non-inbounds geps.
+; CHECK-LABEL: dont_fold_non_inbounds_gep:
+; CHECK: i64.load $push{{[0-9]+}}=, 0($pop{{[0-9]+}})
+define i64 @dont_fold_non_inbounds_gep(i64* %p) {
+bb:
+ %tmp = getelementptr i64, i64* %p, i32 1
+ %tmp2 = load i64, i64* %tmp, align 8
+ ret i64 %tmp2
+}
More information about the llvm-commits
mailing list