[llvm] r261014 - [WebAssemly] Don't move calls or stores past intervening loads

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 16 13:44:20 PST 2016


Author: dschuff
Date: Tue Feb 16 15:44:19 2016
New Revision: 261014

URL: http://llvm.org/viewvc/llvm-project?rev=261014&view=rev
Log:
[WebAssemly] Don't move calls or stores past intervening loads

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.

Differential Revision: http://reviews.llvm.org/D17298

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
    llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp?rev=261014&r1=261013&r2=261014&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp Tue Feb 16 15:44:19 2016
@@ -129,6 +129,7 @@ static bool IsSafeToMove(const MachineIn
       return false;
   }
 
+  SawStore = Def->isCall() || Def->mayStore();
   // Check for memory dependencies and side effects.
   for (--I; I != D; --I)
     SawSideEffects |= !I->isSafeToMove(&AA, SawStore);

Modified: llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll?rev=261014&r1=261013&r2=261014&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll Tue Feb 16 15:44:19 2016
@@ -308,4 +308,43 @@ bb21:
   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 = !{}




More information about the llvm-commits mailing list