[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