Files
clang-p2996/llvm/test/CodeGen/WebAssembly/store-results.ll
Dan Gohman 4b9d7916ee [WebAssembly] Implement instruction selection for constant offsets in addresses.
Add instruction patterns for matching load and store instructions with constant
offsets in addresses. The code is fairly redundant due to the need to replicate
everything between imm, tglobaldadr, and texternalsym, but this appears to be
common tablegen practice. The main alternative appears to be to introduce
matching functions with C++ code, but sticking with purely generated matchers
seems better for now.

Also note that this doesn't yet support offsets from getelementptr, which will
be the most common case; that will depend on a change in target-independent code
in order to set the NoUnsignedWrap flag, which I'll submit separately. Until
then, the testcase uses ptrtoint+add+inttoptr with a nuw on the add.

Also implement isLegalAddressingMode with an approximation of this.

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

llvm-svn: 255681
2015-12-15 22:01:29 +00:00

62 lines
1.9 KiB
LLVM

; RUN: llc < %s -asm-verbose=false | FileCheck %s
; Test that the wasm-store-results pass makes users of stored values use the
; result of store expressions to reduce get_local/set_local traffic.
target datalayout = "e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: single_block:
; CHECK-NOT: .local
; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
; CHECK: i32.store $push[[STORE:[0-9]+]]=, 0($0), $pop{{[0-9]+}}{{$}}
; CHECK: return $pop[[STORE]]{{$}}
define i32 @single_block(i32* %p) {
entry:
store i32 0, i32* %p
ret i32 0
}
; Test interesting corner cases for wasm-store-results, in which the operand of
; a store ends up getting used by a phi, which needs special handling in the
; dominance test, since phis use their operands on their incoming edges.
%class.Vec3 = type { float, float, float }
@pos = global %class.Vec3 zeroinitializer, align 4
; CHECK-LABEL: foo:
; CHECK: i32.store $discard=, pos($0), $0{{$}}
define void @foo() {
for.body.i:
br label %for.body5.i
for.body5.i:
%i.0168.i = phi i32 [ 0, %for.body.i ], [ %inc.i, %for.body5.i ]
%conv6.i = sitofp i32 %i.0168.i to float
store volatile float 0.0, float* getelementptr inbounds (%class.Vec3, %class.Vec3* @pos, i32 0, i32 0)
%inc.i = add nuw nsw i32 %i.0168.i, 1
%exitcond.i = icmp eq i32 %inc.i, 256
br i1 %exitcond.i, label %for.cond.cleanup4.i, label %for.body5.i
for.cond.cleanup4.i:
ret void
}
; CHECK-LABEL: bar:
; CHECK: i32.store $discard=, pos($0), $0{{$}}
define void @bar() {
for.body.i:
br label %for.body5.i
for.body5.i:
%i.0168.i = phi float [ 0.0, %for.body.i ], [ %inc.i, %for.body5.i ]
store volatile float 0.0, float* getelementptr inbounds (%class.Vec3, %class.Vec3* @pos, i32 0, i32 0)
%inc.i = fadd float %i.0168.i, 1.0
%exitcond.i = fcmp oeq float %inc.i, 256.0
br i1 %exitcond.i, label %for.cond.cleanup4.i, label %for.body5.i
for.cond.cleanup4.i:
ret void
}