[WebAssembly] Disable the store-results optimization.
authorDan Gohman <dan433584@gmail.com>
Thu, 18 Aug 2016 17:51:27 +0000 (17:51 +0000)
committerDan Gohman <dan433584@gmail.com>
Thu, 18 Aug 2016 17:51:27 +0000 (17:51 +0000)
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

llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp
llvm/test/CodeGen/WebAssembly/byval.ll
llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
llvm/test/CodeGen/WebAssembly/offset.ll
llvm/test/CodeGen/WebAssembly/reg-stackify.ll
llvm/test/CodeGen/WebAssembly/store-results.ll [deleted file]
llvm/test/CodeGen/WebAssembly/userstack.ll

index eb157dd..40b7d66 100644 (file)
@@ -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);
index ebbf503..40b510d 100644 (file)
@@ -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]
index 241ccf4..0990eb1 100644 (file)
@@ -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:
index fcd8b49..b82d6ba 100644 (file)
@@ -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]]{{$}}
index 23cbd03..9a73db4 100644 (file)
@@ -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 (file)
index 121ee91..0000000
+++ /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
-}
index 66ac2cc..c87be73 100644 (file)
@@ -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.