[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