[PATCH] D17298: [WebAssemly] Don't move calls or stores past intervening loads

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 16 10:41:58 PST 2016


dschuff created this revision.
dschuff added reviewers: sunfish, jfb.
dschuff added a subscriber: llvm-commits.
Herald added a subscriber: jfb.

The register stackifier currently checks for intervening stores (and
loads that may alias them) but doesn't account for the fact that the
instruction being moved may affect intervening loads.

http://reviews.llvm.org/D17298

Files:
  lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
  test/CodeGen/WebAssembly/reg-stackify.ll

Index: test/CodeGen/WebAssembly/reg-stackify.ll
===================================================================
--- test/CodeGen/WebAssembly/reg-stackify.ll
+++ test/CodeGen/WebAssembly/reg-stackify.ll
@@ -308,4 +308,43 @@
   br label %bb5
 }
 
+; Don't move calls past loads
+; CHECK-LABEL: no_stackify_call_past_load:
+; CHECK: i32.call $0=, red
+; CHECK: i32.const $push0=, 0
+; CHECK: i32.load $1=, count($pop0)
+ at count = hidden global i32 0, align 4
+define i32 @no_stackify_call_past_load() {
+  %a = call i32 @red()
+  %b = load i32, i32* @count, align 4
+  call i32 @callee(i32 %a)
+  ret i32 %b
+  ; use of a
+}
+
+; Don't move stores past loads if there may be aliasing
+; CHECK-LABEL: no_stackify_store_past_load
+; CHECK: i32.store {{.*}}, 0($1), $0
+; CHECK: i32.load {{.*}}, 0($2)
+; CHECK: i32.call {{.*}}, callee at FUNCTION, $0
+define i32 @no_stackify_store_past_load(i32 %a, i32* %p1, i32* %p2) {
+  store i32 %a, i32* %p1
+  %b = load i32, i32* %p2, align 4
+  call i32 @callee(i32 %a)
+  ret i32 %b
+}
+
+; Can still stackify past invariant loads.
+; CHECK-LABEL: store_past_invar_load
+; CHECK: i32.store $push{{.*}}, 0($1), $0
+; CHECK: i32.call {{.*}}, callee at FUNCTION, $pop
+; CHECK: i32.load $push{{.*}}, 0($2)
+; CHECK: return $pop
+define i32 @store_past_invar_load(i32 %a, i32* %p1, i32* dereferenceable(4) %p2) {
+  store i32 %a, i32* %p1
+  %b = load i32, i32* %p2, !invariant.load !0
+  call i32 @callee(i32 %a)
+  ret i32 %b
+}
+
 !0 = !{}
Index: lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
===================================================================
--- lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
+++ lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
@@ -129,6 +129,7 @@
       return false;
   }
 
+  SawStore = Def->isCall() || Def->mayStore();
   // Check for memory dependencies and side effects.
   for (--I; I != D; --I)
     SawSideEffects |= !I->isSafeToMove(&AA, SawStore);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17298.48084.patch
Type: text/x-patch
Size: 1939 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160216/38dcb4e7/attachment.bin>


More information about the llvm-commits mailing list