1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[WebAssembly] Fix uses of FrameIndex as store values

Previously the code assumed all uses of FI on loads and stores were as
addresses. This checks whether the use is the address or a value and
handles the latter case as it does for non-memory instructions.

llvm-svn: 259306
This commit is contained in:
Derek Schuff 2016-01-30 21:43:08 +00:00
parent d89bb7340c
commit 2f77371cea
3 changed files with 17 additions and 6 deletions

View File

@ -125,6 +125,8 @@ inline unsigned GetDefaultP2Align(unsigned Opcode) {
}
}
/// The operand number of the load or store address in load/store instructions.
static const unsigned MemOpAddressOperandNo = 2;
/// The operand number of the stored value in a store instruction.
static const unsigned StoreValueOperandNo = 4;

View File

@ -63,9 +63,9 @@ void WebAssemblyRegisterInfo::eliminateFrameIndex(
const MachineFrameInfo &MFI = *MF.getFrameInfo();
int64_t FrameOffset = MFI.getStackSize() + MFI.getObjectOffset(FrameIndex);
if (MI.mayLoadOrStore()) {
// If this is a load or store, make it relative to SP and fold the frame
// offset directly in.
if (MI.mayLoadOrStore() && FIOperandNum == WebAssembly::MemOpAddressOperandNo) {
// If this is the address operand of a load or store, make it relative to SP
// and fold the frame offset directly in.
assert(FrameOffset >= 0 && MI.getOperand(1).getImm() >= 0);
int64_t Offset = MI.getOperand(1).getImm() + FrameOffset;

View File

@ -78,9 +78,10 @@ define void @allocarray() {
declare void @ext_func(i64* %ptr)
; CHECK-LABEL: non_mem_use
define void @non_mem_use() {
; CHECK: i32.const [[L2:.+]]=, 16
define void @non_mem_use(i8** %addr) {
; CHECK: i32.const [[L2:.+]]=, 48
; CHECK-NEXT: i32.sub [[SP:.+]]=, {{.+}}, [[L2]]
%buf = alloca [27 x i8], align 16
%r = alloca i64
%r2 = alloca i64
; %r is at SP+8
@ -91,6 +92,13 @@ define void @non_mem_use() {
; %r2 is at SP+0, no add needed
; CHECK-NEXT: call ext_func@FUNCTION, [[SP]]
call void @ext_func(i64* %r2)
; Use as a value, but in a store
; %buf is at SP+16
; CHECK: i32.const [[OFF:.+]]=, 16
; CHECK-NEXT: i32.add [[VAL:.+]]=, [[SP]], [[OFF]]
; CHECK-NEXT: i32.store {{.*}}=, 0($0), [[VAL]]
%gep = getelementptr inbounds [27 x i8], [27 x i8]* %buf, i32 0, i32 0
store i8* %gep, i8** %addr
ret void
}
@ -151,4 +159,5 @@ define void @dynamic_static_alloca(i32 %alloc) {
; CHECK-NEXT: i32.store [[SP]]=, 0([[L4]]), [[SP]]
ret void
}
; TODO: test aligned alloc
; TODO: test over-aligned alloca