diff options
author | Dan Gohman <dan433584@gmail.com> | 2016-08-18 17:51:27 +0000 |
---|---|---|
committer | Dan Gohman <dan433584@gmail.com> | 2016-08-18 17:51:27 +0000 |
commit | c9623db884ec044249c85366e9bc94e47d5cc48a (patch) | |
tree | 70ad6fd8b0ee4e7c9e6cb736699348a48a612548 | |
parent | e2f36bcb84219bcb1298e5245f6507b638645673 (diff) | |
download | bcm5719-llvm-c9623db884ec044249c85366e9bc94e47d5cc48a.tar.gz bcm5719-llvm-c9623db884ec044249c85366e9bc94e47d5cc48a.zip |
[WebAssembly] Disable the store-results optimization.
The WebAssemly spec removing the return value from store instructions, so
remove the associated optimization from LLVM.
This patch leaves the store instruction operands in place for now, so stores
now always write to "$drop"; these will be removed in a seperate patch.
llvm-svn: 279100
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp | 20 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/byval.ll | 29 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/cfg-stackify.ll | 12 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/offset.ll | 9 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/reg-stackify.ll | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/store-results.ll | 72 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/userstack.ll | 72 |
7 files changed, 70 insertions, 154 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp index eb157ddd700..40b7d665f05 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp @@ -139,15 +139,6 @@ static bool ReplaceDominatedUses(MachineBasicBlock &MBB, MachineInstr &MI, return Changed; } -static bool optimizeStore(MachineBasicBlock &MBB, MachineInstr &MI, - const MachineRegisterInfo &MRI, - MachineDominatorTree &MDT, - LiveIntervals &LIS) { - unsigned ToReg = MI.getOperand(0).getReg(); - unsigned FromReg = MI.getOperand(WebAssembly::StoreValueOperandNo).getReg(); - return ReplaceDominatedUses(MBB, MI, FromReg, ToReg, MRI, MDT, LIS); -} - static bool optimizeCall(MachineBasicBlock &MBB, MachineInstr &MI, const MachineRegisterInfo &MRI, MachineDominatorTree &MDT, @@ -202,17 +193,6 @@ bool WebAssemblyStoreResults::runOnMachineFunction(MachineFunction &MF) { switch (MI.getOpcode()) { default: break; - case WebAssembly::STORE8_I32: - case WebAssembly::STORE16_I32: - case WebAssembly::STORE8_I64: - case WebAssembly::STORE16_I64: - case WebAssembly::STORE32_I64: - case WebAssembly::STORE_F32: - case WebAssembly::STORE_F64: - case WebAssembly::STORE_I32: - case WebAssembly::STORE_I64: - Changed |= optimizeStore(MBB, MI, MRI, MDT, LIS); - break; case WebAssembly::CALL_I32: case WebAssembly::CALL_I64: Changed |= optimizeCall(MBB, MI, MRI, MDT, LIS, TLI, LibInfo); diff --git a/llvm/test/CodeGen/WebAssembly/byval.ll b/llvm/test/CodeGen/WebAssembly/byval.ll index ebbf50313a5..40b510da7cc 100644 --- a/llvm/test/CodeGen/WebAssembly/byval.ll +++ b/llvm/test/CodeGen/WebAssembly/byval.ll @@ -28,13 +28,13 @@ define void @byval_arg(%SmallStruct* %ptr) { ; CHECK: i32.const $push[[L1:.+]]=, 0 ; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]]) ; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16 - ; CHECK-NEXT: i32.sub $push[[L10:.+]]=, $pop[[L2]], $pop[[L3]] + ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]] ; Ensure SP is stored back before the call - ; CHECK-NEXT: i32.store $push[[L12:.+]]=, __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}} - ; CHECK-NEXT: tee_local $push[[L11:.+]]=, $[[SP:.+]]=, $pop[[L12]]{{$}} + ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}} + ; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}} ; Copy the SmallStruct argument to the stack (SP+12, original SP-4) ; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0) - ; CHECK-NEXT: i32.store $drop=, 12($pop[[L11]]), $pop[[L0]] + ; CHECK-NEXT: i32.store $drop=, 12($[[SP]]), $pop[[L0]] ; Pass a pointer to the stack slot to the function ; CHECK-NEXT: i32.const $push[[L5:.+]]=, 12{{$}} ; CHECK-NEXT: i32.add $push[[ARG:.+]]=, $[[SP]], $pop[[L5]]{{$}} @@ -54,12 +54,12 @@ define void @byval_arg_align8(%SmallStruct* %ptr) { ; CHECK: .param i32 ; Don't check the entire SP sequence, just enough to get the alignment. ; CHECK: i32.const $push[[L1:.+]]=, 16 - ; CHECK-NEXT: i32.sub $push[[L10:.+]]=, {{.+}}, $pop[[L1]] - ; CHECK-NEXT: i32.store $push[[L12:.+]]=, __stack_pointer($pop{{.+}}), $pop[[L10]]{{$}} - ; CHECK-NEXT: tee_local $push[[L11:.+]]=, $[[SP:.+]]=, $pop[[L12]]{{$}} + ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, {{.+}}, $pop[[L1]] + ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}} + ; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop{{.+}}), $pop[[L10]]{{$}} ; Copy the SmallStruct argument to the stack (SP+8, original SP-8) ; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0){{$}} - ; CHECK-NEXT: i32.store $drop=, 8($pop[[L11]]), $pop[[L0]]{{$}} + ; CHECK-NEXT: i32.store $drop=, 8($[[SP]]), $pop[[L0]]{{$}} ; Pass a pointer to the stack slot to the function ; CHECK-NEXT: i32.const $push[[L5:.+]]=, 8{{$}} ; CHECK-NEXT: i32.add $push[[ARG:.+]]=, $[[SP]], $pop[[L5]]{{$}} @@ -73,9 +73,9 @@ define void @byval_arg_double(%AlignedStruct* %ptr) { ; CHECK: .param i32 ; Subtract 16 from SP (SP is 16-byte aligned) ; CHECK: i32.const $push[[L1:.+]]=, 16 - ; CHECK-NEXT: i32.sub $push[[L12:.+]]=, {{.+}}, $pop[[L1]] - ; CHECK-NEXT: i32.store $push[[L15:.+]]=, {{.+}}, $pop[[L12]] - ; CHECK-NEXT: tee_local $push[[L14:.+]]=, $[[SP:.+]]=, $pop[[L15]] + ; CHECK-NEXT: i32.sub $push[[L14:.+]]=, {{.+}}, $pop[[L1]] + ; CHECK-NEXT: tee_local $push[[L13:.+]]=, $[[SP:.+]]=, $pop[[L14]] + ; CHECK-NEXT: i32.store $drop=, {{.+}}, $pop[[L13]] ; Copy the AlignedStruct argument to the stack (SP+0, original SP-16) ; Just check the last load/store pair of the memcpy ; CHECK: i64.load $push[[L4:.+]]=, 0($0) @@ -117,10 +117,11 @@ define void @byval_empty_callee(%EmptyStruct* byval %ptr) { ; CHECK: i32.const $push[[L1:.+]]=, 0 ; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]]) ; CHECK-NEXT: i32.const $push[[L3:.+]]=, 131072 -; CHECK-NEXT: i32.sub $push[[L8:.+]]=, $pop[[L2]], $pop[[L3]] -; CHECK-NEXT: i32.store $push[[L12:.+]]=, __stack_pointer($pop[[L4]]), $pop[[L8]]{{$}} +; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]] +; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}} +; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}} ; CHECK-NEXT: i32.const $push[[L0:.+]]=, 131072 -; CHECK-NEXT: i32.call $push[[L11:.+]]=, memcpy@FUNCTION, $pop{{.+}}, ${{.+}}, $pop{{.+}} +; CHECK-NEXT: i32.call $push[[L11:.+]]=, memcpy@FUNCTION, $[[SP]], ${{.+}}, $pop{{.+}} ; CHECK-NEXT: tee_local $push[[L9:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}} ; CHECK-NEXT: call big_byval_callee@FUNCTION, %big = type [131072 x i8] diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll index 241ccf4b885..0990eb186d6 100644 --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll @@ -207,12 +207,12 @@ exit: ; CHECK: block{{$}} ; CHECK: br_if 0, $1{{$}} ; CHECK: .LBB4_2: -; CHECK: return ${{[0-9]+}}{{$}} +; CHECK: return ; OPT-LABEL: triangle: ; OPT: block{{$}} ; OPT: br_if 0, $1{{$}} ; OPT: .LBB4_2: -; OPT: return ${{[0-9]+}}{{$}} +; OPT: return define i32 @triangle(i32* %p, i32 %a) { entry: %c = icmp eq i32 %a, 0 @@ -329,7 +329,7 @@ exit: ; CHECK: br_if 0, $1{{$}} ; CHECK: .LBB9_3: ; CHECK: .LBB9_4: -; CHECK: return ${{[0-9]+}}{{$}} +; CHECK: return ; OPT-LABEL: doubletriangle: ; OPT: block{{$}} ; OPT: br_if 0, $0{{$}} @@ -337,7 +337,7 @@ exit: ; OPT: br_if 0, $1{{$}} ; OPT: .LBB9_3: ; OPT: .LBB9_4: -; OPT: return ${{[0-9]+}}{{$}} +; OPT: return define i32 @doubletriangle(i32 %a, i32 %b, i32* %p) { entry: %c = icmp eq i32 %a, 0 @@ -965,6 +965,7 @@ bb6: ; CHECK: br_if 0, {{[^,]+}}{{$}} ; CHECK-NOT: block ; CHECK: block{{$}} +; CHECK-NEXT: i32.const ; CHECK-NEXT: br_if 0, {{[^,]+}}{{$}} ; CHECK-NOT: block ; CHECK: br_if 2, {{[^,]+}}{{$}} @@ -996,7 +997,8 @@ bb6: ; OPT: br_if 0, $pop{{[0-9]+}}{{$}} ; OPT-NOT: block ; OPT: block{{$}} -; OPT-NEXT: br_if 0, $0{{$}} +; OPT-NEXT: i32.const +; OPT-NEXT: br_if 0, {{[^,]+}}{{$}} ; OPT-NOT: block ; OPT: br_if 2, {{[^,]+}}{{$}} ; OPT-NEXT: .LBB20_3: diff --git a/llvm/test/CodeGen/WebAssembly/offset.ll b/llvm/test/CodeGen/WebAssembly/offset.ll index fcd8b49758e..b82d6ba1660 100644 --- a/llvm/test/CodeGen/WebAssembly/offset.ll +++ b/llvm/test/CodeGen/WebAssembly/offset.ll @@ -398,7 +398,8 @@ define void @aggregate_load_store({i32,i32,i32,i32}* %p, {i32,i32,i32,i32}* %q) ; CHECK-LABEL: aggregate_return: ; CHECK: i64.const $push[[L0:[0-9]+]]=, 0{{$}} -; CHECK: i64.store $push[[L1:[0-9]+]]=, 8($0):p2align=2, $pop[[L0]]{{$}} +; CHECK: i64.store $drop=, 8($0):p2align=2, $pop[[L0]]{{$}} +; CHECK: i64.const $push[[L1:[0-9]+]]=, 0{{$}} ; CHECK: i64.store $drop=, 0($0):p2align=2, $pop[[L1]]{{$}} define {i32,i32,i32,i32} @aggregate_return() { ret {i32,i32,i32,i32} zeroinitializer @@ -409,8 +410,10 @@ define {i32,i32,i32,i32} @aggregate_return() { ; CHECK-LABEL: aggregate_return_without_merge: ; CHECK: i32.const $push[[L0:[0-9]+]]=, 0{{$}} -; CHECK: i32.store8 $push[[L1:[0-9]+]]=, 14($0), $pop[[L0]]{{$}} -; CHECK: i32.store16 $push[[L2:[0-9]+]]=, 12($0), $pop[[L1]]{{$}} +; CHECK: i32.store8 $drop=, 14($0), $pop[[L0]]{{$}} +; CHECK: i32.const $push[[L1:[0-9]+]]=, 0{{$}} +; CHECK: i32.store16 $drop=, 12($0), $pop[[L1]]{{$}} +; CHECK: i32.const $push[[L2:[0-9]+]]=, 0{{$}} ; CHECK: i32.store $drop=, 8($0), $pop[[L2]]{{$}} ; CHECK: i64.const $push[[L3:[0-9]+]]=, 0{{$}} ; CHECK: i64.store $drop=, 0($0), $pop[[L3]]{{$}} diff --git a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll index 23cbd03aa08..9a73db45c51 100644 --- a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll +++ b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll @@ -166,7 +166,7 @@ return: ; CHECK: side_effects: ; CHECK: store ; CHECK-NEXT: call -; CHECK-NEXT: store +; CHECK: store ; CHECK-NEXT: call declare void @evoke_side_effects() define hidden void @stackify_store_across_side_effects(double* nocapture %d) { @@ -377,9 +377,9 @@ define i32 @no_stackify_call_past_load() { ; Don't move stores past loads if there may be aliasing ; CHECK-LABEL: no_stackify_store_past_load -; CHECK: i32.store $[[L0:[0-9]+]]=, 0($1), $0 +; CHECK: i32.store $drop=, 0($1), $0 ; CHECK: i32.load {{.*}}, 0($2) -; CHECK: i32.call {{.*}}, callee@FUNCTION, $[[L0]]{{$}} +; 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 @@ -389,8 +389,8 @@ define i32 @no_stackify_store_past_load(i32 %a, i32* %p1, i32* %p2) { ; 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.store $drop=, 0($1), $0 +; CHECK: i32.call {{.*}}, callee@FUNCTION, $0 ; CHECK: i32.load $push{{.*}}, 0($2) ; CHECK: return $pop define i32 @store_past_invar_load(i32 %a, i32* %p1, i32* dereferenceable(4) %p2) { diff --git a/llvm/test/CodeGen/WebAssembly/store-results.ll b/llvm/test/CodeGen/WebAssembly/store-results.ll deleted file mode 100644 index 121ee910f85..00000000000 --- a/llvm/test/CodeGen/WebAssembly/store-results.ll +++ /dev/null @@ -1,72 +0,0 @@ -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | 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-m: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 $drop=, pos($pop{{[0-9]+}}), $pop{{[0-9]+}}{{$}} -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 $drop=, pos($pop{{[0-9]+}}), $pop{{[0-9]+}}{{$}} -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 -} - -; CHECK-LABEL: fi_ret: -; CHECK: i32.store $push0=, -; CHECK: return $pop0{{$}} -define hidden i8* @fi_ret(i8** %addr) { -entry: - %buf = alloca [27 x i8], align 16 - %0 = getelementptr inbounds [27 x i8], [27 x i8]* %buf, i32 0, i32 0 - store i8* %0, i8** %addr - ret i8* %0 -} diff --git a/llvm/test/CodeGen/WebAssembly/userstack.ll b/llvm/test/CodeGen/WebAssembly/userstack.ll index 66ac2cce707..c87be7326ca 100644 --- a/llvm/test/CodeGen/WebAssembly/userstack.ll +++ b/llvm/test/CodeGen/WebAssembly/userstack.ll @@ -14,12 +14,12 @@ define void @alloca32() noredzone { ; CHECK: i32.const $push[[L1:.+]]=, 0{{$}} ; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]]) ; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16 - ; CHECK-NEXT: i32.sub $push[[L8:.+]]=, $pop[[L2]], $pop[[L3]] - ; CHECK-NEXT: i32.store $push[[L10:.+]]=, __stack_pointer($pop[[L4]]), $pop[[L8]]{{$}} - ; CHECK-NEXT: tee_local $push[[L9:.+]]=, $[[SP:.+]]=, $pop[[L10]]{{$}} + ; CHECK-NEXT: i32.sub $push[[L9:.+]]=, $pop[[L2]], $pop[[L3]] + ; CHECK-NEXT: tee_local $push[[L8:.+]]=, $[[SP:.+]]=, $pop[[L9]]{{$}} + ; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L4]]), $pop[[L8]]{{$}} %retval = alloca i32 ; CHECK: i32.const $push[[L0:.+]]=, 0 - ; CHECK: i32.store {{.*}}=, 12($pop[[L9]]), $pop[[L0]] + ; CHECK: i32.store $drop=, 12($[[SP]]), $pop[[L0]] store i32 0, i32* %retval ; CHECK: i32.const $push[[L6:.+]]=, 0 ; CHECK-NEXT: i32.const $push[[L5:.+]]=, 16 @@ -51,43 +51,45 @@ define void @alloca3264() { ; CHECK-LABEL: allocarray: ; CHECK: .local i32{{$}} define void @allocarray() { - ; CHECK: i32.const $push[[L7:.+]]=, 0{{$}} - ; CHECK: i32.const $push[[L4:.+]]=, 0{{$}} - ; CHECK-NEXT: i32.load $push[[L5:.+]]=, __stack_pointer($pop[[L4]]) - ; CHECK-NEXT: i32.const $push[[L6:.+]]=, 144{{$}} - ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L5]], $pop[[L6]] - ; CHECK-NEXT: i32.store ${{.+}}=, __stack_pointer($pop[[L7]]), $pop[[L11]] + ; CHECK: i32.const $push[[L6:.+]]=, 0{{$}} + ; CHECK: i32.const $push[[L3:.+]]=, 0{{$}} + ; CHECK-NEXT: i32.load $push[[L4:.+]]=, __stack_pointer($pop[[L3]]) + ; CHECK-NEXT: i32.const $push[[L5:.+]]=, 144{{$}} + ; CHECK-NEXT: i32.sub $push[[L12:.+]]=, $pop[[L4]], $pop[[L5]] + ; CHECK-NEXT: tee_local $push[[L11:.+]]=, $0=, $pop[[L12]] + ; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L6]]), $pop[[L11]] %r = alloca [33 x i32] ; CHECK: i32.const $push{{.+}}=, 24 ; CHECK-NEXT: i32.add $push[[L3:.+]]=, $[[SP]], $pop{{.+}} ; CHECK-NEXT: i32.const $push[[L1:.+]]=, 1{{$}} - ; CHECK-NEXT: i32.store $push[[L0:.+]]=, 0($pop[[L3]]), $pop[[L1]]{{$}} - ; CHECK-NEXT: i32.store $drop=, 12(${{.+}}), $pop[[L0]]{{$}} + ; CHECK-NEXT: i32.store $drop=, 0($pop[[L3]]), $pop[[L1]]{{$}} + ; CHECK-NEXT: i32.const $push[[L10:.+]]=, 1{{$}} + ; CHECK-NEXT: i32.store $drop=, 12(${{.+}}), $pop[[L10]]{{$}} %p = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 0 store i32 1, i32* %p %p2 = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 3 store i32 1, i32* %p2 - ; CHECK: i32.const $push[[L10:.+]]=, 0{{$}} - ; CHECK-NEXT: i32.const $push[[L8:.+]]=, 144 - ; CHECK-NEXT: i32.add $push[[L19:.+]]=, $[[SP]], $pop[[L8]] - ; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L10]]), $pop[[L9]] + ; CHECK: i32.const $push[[L9:.+]]=, 0{{$}} + ; CHECK-NEXT: i32.const $push[[L7:.+]]=, 144 + ; CHECK-NEXT: i32.add $push[[L8:.+]]=, $[[SP]], $pop[[L7]] + ; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L9]]), $pop[[L8]] ret void } ; CHECK-LABEL: non_mem_use define void @non_mem_use(i8** %addr) { - ; CHECK: i32.const $push[[L1:.+]]=, 48 - ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, {{.+}}, $pop[[L1]] - ; CHECK-NEXT: i32.store $[[SP:.+]]=, {{.+}}, $pop[[L11]] + ; CHECK: i32.const $push[[L2:.+]]=, 48 + ; CHECK-NEXT: i32.sub $push[[L12:.+]]=, {{.+}}, $pop[[L2]] + ; CHECK-NEXT: tee_local $push[[L11:.+]]=, $[[SP:.+]]=, $pop[[L12]] + ; CHECK-NEXT: i32.store $drop=, {{.+}}, $pop[[L11]] %buf = alloca [27 x i8], align 16 %r = alloca i64 %r2 = alloca i64 ; %r is at SP+8 - ; CHECK: tee_local $push[[L12:.+]]=, $[[SP:.+]]=, $pop{{.+}} ; CHECK: i32.const $push[[OFF:.+]]=, 8 - ; CHECK-NEXT: i32.add $push[[ARG1:.+]]=, $pop[[L12]], $pop[[OFF]] + ; CHECK-NEXT: i32.add $push[[ARG1:.+]]=, $[[SP]], $pop[[OFF]] ; CHECK-NEXT: call ext_func@FUNCTION, $pop[[ARG1]] call void @ext_func(i64* %r) ; %r2 is at SP+0, no add needed @@ -97,7 +99,7 @@ define void @non_mem_use(i8** %addr) { ; %buf is at SP+16 ; CHECK: i32.const $push[[OFF:.+]]=, 16 ; CHECK-NEXT: i32.add $push[[VAL:.+]]=, $[[SP]], $pop[[OFF]] - ; CHECK-NEXT: i32.store {{.*}}=, 0($0), $pop[[VAL]] + ; CHECK-NEXT: i32.store $drop=, 0($0), $pop[[VAL]] %gep = getelementptr inbounds [27 x i8], [27 x i8]* %buf, i32 0, i32 0 store i8* %gep, i8** %addr ret void @@ -106,15 +108,16 @@ define void @non_mem_use(i8** %addr) { ; CHECK-LABEL: allocarray_inbounds: ; CHECK: .local i32{{$}} define void @allocarray_inbounds() { - ; CHECK: i32.const $push[[L6:.+]]=, 0{{$}} - ; CHECK: i32.const $push[[L3:.+]]=, 0{{$}} - ; CHECK-NEXT: i32.load $push[[L4:.+]]=, __stack_pointer($pop[[L3]]) - ; CHECK-NEXT: i32.const $push[[L5:.+]]=, 32{{$}} - ; CHECK-NEXT: i32.sub $push[[L10:.+]]=, $pop[[L4]], $pop[[L5]] - ; CHECK-NEXT: i32.store ${{.+}}=, __stack_pointer($pop[[L6]]), $pop[[L10]]{{$}} + ; CHECK: i32.const $push[[L5:.+]]=, 0{{$}} + ; CHECK: i32.const $push[[L2:.+]]=, 0{{$}} + ; CHECK-NEXT: i32.load $push[[L3:.+]]=, __stack_pointer($pop[[L2]]) + ; CHECK-NEXT: i32.const $push[[L4:.+]]=, 32{{$}} + ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L3]], $pop[[L4]] + ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]] + ; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L5]]), $pop[[L10]]{{$}} %r = alloca [5 x i32] ; CHECK: i32.const $push[[L3:.+]]=, 1 - ; CHECK-DAG: i32.store $push{{.*}}=, 24(${{.+}}), $pop[[L3]] + ; CHECK-DAG: i32.store $drop=, 24(${{.+}}), $pop[[L3]] %p = getelementptr inbounds [5 x i32], [5 x i32]* %r, i32 0, i32 0 store i32 1, i32* %p ; This store should have both the GEP and the FI folded into it. @@ -170,14 +173,13 @@ define void @dynamic_alloca_redzone(i32 %alloc) { ; CHECK-LABEL: dynamic_static_alloca: define void @dynamic_static_alloca(i32 %alloc) noredzone { ; Decrement SP in the prolog by the static amount and writeback to memory. - ; CHECK: i32.const $push[[L7:.+]]=, 0{{$}} + ; CHECK: i32.const $push[[L11:.+]]=, 0{{$}} ; CHECK: i32.const $push[[L8:.+]]=, 0{{$}} - ; CHECK: i32.const $push[[L9:.+]]=, 0{{$}} - ; CHECK-NEXT: i32.load $push[[L10:.+]]=, __stack_pointer($pop[[L9]]) - ; CHECK-NEXT: i32.const $push[[L11:.+]]=, 16 - ; CHECK-NEXT: i32.sub $push[[L20:.+]]=, $pop[[L10]], $pop[[L11]] + ; CHECK-NEXT: i32.load $push[[L9:.+]]=, __stack_pointer($pop[[L8]]) + ; CHECK-NEXT: i32.const $push[[L10:.+]]=, 16 + ; CHECK-NEXT: i32.sub $push[[L20:.+]]=, $pop[[L9]], $pop[[L10]] ; CHECK-NEXT: tee_local $push[[L19:.+]]=, $[[FP:.+]]=, $pop[[L20]] - ; CHECK: i32.store $push[[L0:.+]]=, __stack_pointer($pop{{.+}}), $pop{{.+}} + ; CHECK: i32.store $drop=, __stack_pointer($pop{{.+}}), $pop{{.+}} ; Decrement SP in the body by the dynamic amount. ; CHECK: i32.sub ; Writeback to memory. |