From c97ba939d15c4d6dc371e9ccf7cd88d1e8c32768 Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Sat, 30 Jan 2016 21:43:08 +0000 Subject: [PATCH] [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 --- .../WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h | 2 ++ llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp | 6 +++--- llvm/test/CodeGen/WebAssembly/userstack.ll | 15 ++++++++++++--- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h index df541f8..af97092 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -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; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp index 3397f59..607fd6e 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp @@ -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; diff --git a/llvm/test/CodeGen/WebAssembly/userstack.ll b/llvm/test/CodeGen/WebAssembly/userstack.ll index 4da1324..435e1dd 100644 --- a/llvm/test/CodeGen/WebAssembly/userstack.ll +++ b/llvm/test/CodeGen/WebAssembly/userstack.ll @@ -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 -- 2.7.4