mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 11:02:59 +02:00
[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 llvm-svn: 261014
This commit is contained in:
parent
e39424112f
commit
b9542a8754
@ -129,6 +129,7 @@ static bool IsSafeToMove(const MachineInstr *Def, const MachineInstr *Insert,
|
||||
return false;
|
||||
}
|
||||
|
||||
SawStore = Def->isCall() || Def->mayStore();
|
||||
// Check for memory dependencies and side effects.
|
||||
for (--I; I != D; --I)
|
||||
SawSideEffects |= !I->isSafeToMove(&AA, SawStore);
|
||||
|
@ -308,4 +308,43 @@ bb21: ; preds = %bb17, %bb5
|
||||
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)
|
||||
@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@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@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 = !{}
|
||||
|
Loading…
Reference in New Issue
Block a user