[WebAssembly] Rematerialize constants rather than hold them live in registers.
Teach the register stackifier to rematerialize constants that have multiple
uses instead of leaving them in registers. In the WebAssembly encoding, it's
the same code size to materialize most constants as it is to read a value
from a register.
llvm-svn: 258142
diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
index f0e5f44..196bed0 100644
--- a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
+++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
@@ -147,7 +147,8 @@
; CHECK-NEXT: end_block{{$}}
; CHECK: .LBB3_5:
; CHECK-NEXT: end_block{{$}}
-; CHECK: return ${{[0-9]+}}{{$}}
+; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
+; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
; OPT-LABEL: doublediamond:
; OPT: block{{$}}
; OPT-NEXT: block{{$}}
@@ -157,7 +158,8 @@
; OPT: br 1{{$}}
; OPT: .LBB3_4:
; OPT: .LBB3_5:
-; OPT: return ${{[0-9]+}}{{$}}
+; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
+; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
define i32 @doublediamond(i32 %a, i32 %b, i32* %p) {
entry:
%c = icmp eq i32 %a, 0
@@ -211,7 +213,8 @@
; CHECK: br 1{{$}}
; CHECK: .LBB5_2:
; CHECK: .LBB5_3:
-; CHECK: return ${{[0-9]+}}{{$}}
+; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
+; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
; OPT-LABEL: diamond:
; OPT: block{{$}}
; OPT: block{{$}}
@@ -219,7 +222,8 @@
; OPT: br 1{{$}}
; OPT: .LBB5_2:
; OPT: .LBB5_3:
-; OPT: return ${{[0-9]+}}{{$}}
+; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
+; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
define i32 @diamond(i32* %p, i32 %a) {
entry:
%c = icmp eq i32 %a, 0
@@ -275,14 +279,16 @@
; CHECK: loop{{$}}
; CHECK: br_if $pop{{[0-9]+}}, 0{{$}}
; CHECK-NEXT: end_loop{{$}}
-; CHECK: return ${{[0-9]+}}{{$}}
+; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
+; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
; OPT-LABEL: simple_loop:
; OPT-NOT: br
; OPT: .LBB8_1:
; OPT: loop{{$}}
; OPT: br_if {{[^,]*}}, 0{{$}}
; OPT-NEXT: end_loop{{$}}
-; OPT: return ${{[0-9]+}}{{$}}
+; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
+; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
define i32 @simple_loop(i32* %p, i32 %a) {
entry:
%c = icmp eq i32 %a, 0
@@ -340,7 +346,8 @@
; CHECK: .LBB10_2:
; CHECK: br_if $1, 0{{$}}
; CHECK: .LBB10_4:
-; CHECK: return ${{[0-9]+}}{{$}}
+; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
+; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
; OPT-LABEL: ifelse_earlyexits:
; OPT: block{{$}}
; OPT: block{{$}}
@@ -349,7 +356,8 @@
; OPT: br 1{{$}}
; OPT: .LBB10_3:
; OPT: .LBB10_4:
-; OPT: return ${{[0-9]+}}{{$}}
+; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
+; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
define i32 @ifelse_earlyexits(i32 %a, i32 %b, i32* %p) {
entry:
%c = icmp eq i32 %a, 0
@@ -733,6 +741,7 @@
; CHECK-NEXT: .LBB17_3:
; CHECK-NEXT: end_block{{$}}
; CHECK-NEXT: loop{{$}}
+; CHECK-NEXT: i32.const $push{{[^,]*}}, 0{{$}}
; CHECK-NEXT: br_if {{[^,]*}}, 0{{$}}
; CHECK-NEXT: br 2{{$}}
; CHECK-NEXT: .LBB17_4:
@@ -747,6 +756,7 @@
; OPT-NEXT: .LBB17_3:
; OPT-NEXT: end_block{{$}}
; OPT-NEXT: loop{{$}}
+; OPT-NEXT: i32.const $push{{[^,]*}}, 0{{$}}
; OPT-NEXT: br_if {{[^,]*}}, 0{{$}}
; OPT-NEXT: br 2{{$}}
; OPT-NEXT: .LBB17_4:
@@ -938,7 +948,7 @@
; CHECK-NEXT: block{{$}}
; CHECK-NEXT: block{{$}}
; CHECK-NEXT: block{{$}}
-; CHECK-NEXT: br_if {{[^,]*}}, 0{{$}}
+; CHECK: br_if {{[^,]*}}, 0{{$}}
; CHECK-NEXT: block{{$}}
; CHECK-NOT: block
; CHECK: br_if {{[^,]*}}, 0{{$}}
@@ -969,12 +979,12 @@
; OPT-LABEL: test11:
; OPT: block{{$}}
; OPT-NEXT: block{{$}}
-; OPT-NEXT: br_if $0, 0{{$}}
+; OPT: br_if $0, 0{{$}}
; OPT-NEXT: block{{$}}
; OPT-NOT: block
; OPT: br_if $0, 0{{$}}
; OPT-NOT: block
-; OPT: br_if $0, 2{{$}}
+; OPT: br_if {{[^,]*}}, 2{{$}}
; OPT-NEXT: .LBB20_3:
; OPT-NEXT: end_block{{$}}
; OPT-NOT: block
@@ -984,13 +994,13 @@
; OPT-NOT: block
; OPT: block{{$}}
; OPT-NOT: block
-; OPT: br_if $pop9, 0{{$}}
+; OPT: br_if $pop{{[0-9]+}}, 0{{$}}
; OPT-NOT: block
; OPT: return{{$}}
; OPT-NEXT: .LBB20_6:
; OPT-NEXT: end_block{{$}}
; OPT-NOT: block
-; OPT: br_if $0, 0{{$}}
+; OPT: br_if $pop{{[0-9]+}}, 0{{$}}
; OPT-NOT: block
; OPT: return{{$}}
; OPT-NEXT: .LBB20_8:
@@ -1109,7 +1119,7 @@
; optnone to disable optimizations to test this case.
; CHECK-LABEL: test13:
-; CHECK-NEXT: local i32{{$}}
+; CHECK-NEXT: .local i32{{$}}
; CHECK: block{{$}}
; CHECK: br_if $pop4, 0{{$}}
; CHECK-NEXT: return{{$}}
@@ -1124,7 +1134,7 @@
; CHECK-NEXT: end_block{{$}}
; CHECK-NEXT: unreachable{{$}}
; OPT-LABEL: test13:
-; OPT-NEXT: local i32{{$}}
+; OPT-NEXT: .local i32{{$}}
; OPT: block{{$}}
; OPT: br_if $pop4, 0{{$}}
; OPT-NEXT: return{{$}}
@@ -1159,15 +1169,16 @@
; before the loop for the second.
; CHECK-LABEL: test14:
-; CHECK-NEXT: local i32{{$}}
-; CHECK-NEXT: i32.const $0=, 0{{$}}
; CHECK-NEXT: .LBB23_1:{{$}}
; CHECK-NEXT: loop{{$}}
-; CHECK-NEXT: br_if $0, 0{{$}}
+; CHECK-NEXT: i32.const $push0=, 0{{$}}
+; CHECK-NEXT: br_if $pop0, 0{{$}}
; CHECK-NEXT: .LBB23_2:{{$}}
; CHECK-NEXT: end_loop{{$}}
; CHECK-NEXT: loop{{$}}
-; CHECK-NEXT: br_if $0, 0{{$}}
+; CHECK-NEXT: i32.const $push1=, 0{{$}}
+; CHECK-NEXT: i32.const $push2=, 0{{$}}
+; CHECK-NEXT: br_if $pop2, 0{{$}}
; CHECK-NEXT: end_loop{{$}}
; CHECK-NEXT: return{{$}}
define void @test14() {
diff --git a/llvm/test/CodeGen/WebAssembly/dead-vreg.ll b/llvm/test/CodeGen/WebAssembly/dead-vreg.ll
index 29a4199..190a085 100644
--- a/llvm/test/CodeGen/WebAssembly/dead-vreg.ll
+++ b/llvm/test/CodeGen/WebAssembly/dead-vreg.ll
@@ -8,7 +8,7 @@
define void @foo(i32* nocapture %a, i32 %w, i32 %h) {
; CHECK-LABEL: foo:
; CHECK-NEXT: .param i32, i32, i32{{$}}
-; CHECK-NEXT: .local i32, i32, i32, i32, i32, i32, i32{{$}}
+; CHECK-NEXT: .local i32, i32, i32, i32, i32, i32{{$}}
entry:
%cmp.19 = icmp sgt i32 %h, 0
br i1 %cmp.19, label %for.cond.1.preheader.lr.ph, label %for.end.7
diff --git a/llvm/test/CodeGen/WebAssembly/func.ll b/llvm/test/CodeGen/WebAssembly/func.ll
index 9857dad..b7122a3 100644
--- a/llvm/test/CodeGen/WebAssembly/func.ll
+++ b/llvm/test/CodeGen/WebAssembly/func.ll
@@ -44,7 +44,8 @@
; CHECK-LABEL: f4:
; CHECK-NEXT: .param i32{{$}}
; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: local
+; CHECK-NOT: local
+; CHECK: .size f4,
define i32 @f4(i32 %x) {
entry:
%c = trunc i32 %x to i1
diff --git a/llvm/test/CodeGen/WebAssembly/load-store-i1.ll b/llvm/test/CodeGen/WebAssembly/load-store-i1.ll
index 47e2e8c..fb90d00 100644
--- a/llvm/test/CodeGen/WebAssembly/load-store-i1.ll
+++ b/llvm/test/CodeGen/WebAssembly/load-store-i1.ll
@@ -15,10 +15,11 @@
}
; CHECK-LABEL: load_s_i1_i32:
-; CHECK: i32.const $[[NUM1:[0-9]+]]=, 31{{$}}
-; CHECK-NEXT: i32.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}
-; CHECK-NEXT: shl $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $[[NUM1]]{{$}}
-; CHECK-NEXT: shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $[[NUM1]]{{$}}
+; CHECK: i32.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}
+; CHECK-NEXT: i32.const $push[[NUM1:[0-9]+]]=, 31{{$}}
+; CHECK-NEXT: shl $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM4:[0-9]+]]=, 31{{$}}
+; CHECK-NEXT: shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $pop[[NUM4]]{{$}}
; CHECK-NEXT: return $pop[[NUM3]]{{$}}
define i32 @load_s_i1_i32(i1* %p) {
%v = load i1, i1* %p
@@ -36,10 +37,11 @@
}
; CHECK-LABEL: load_s_i1_i64:
-; CHECK: i64.const $[[NUM1:[0-9]+]]=, 63{{$}}
-; CHECK-NEXT: i64.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}
-; CHECK-NEXT: shl $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $[[NUM1]]{{$}}
-; CHECK-NEXT: shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $[[NUM1]]{{$}}
+; CHECK: i64.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}
+; CHECK-NEXT: i64.const $push[[NUM1:[0-9]+]]=, 63{{$}}
+; CHECK-NEXT: shl $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
+; CHECK-NEXT: i64.const $push[[NUM4:[0-9]+]]=, 63{{$}}
+; CHECK-NEXT: shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $pop[[NUM4]]{{$}}
; CHECK-NEXT: return $pop[[NUM3]]{{$}}
define i64 @load_s_i1_i64(i1* %p) {
%v = load i1, i1* %p
diff --git a/llvm/test/CodeGen/WebAssembly/offset.ll b/llvm/test/CodeGen/WebAssembly/offset.ll
index 828f402..ba0f72c 100644
--- a/llvm/test/CodeGen/WebAssembly/offset.ll
+++ b/llvm/test/CodeGen/WebAssembly/offset.ll
@@ -266,8 +266,9 @@
}
; CHECK-LABEL: store_i32_to_numeric_address:
-; CHECK: i32.const $0=, 0{{$}}
-; CHECK: i32.store $discard=, 42($0), $0{{$}}
+; CHECK-NEXT: i32.const $push0=, 0{{$}}
+; CHECK-NEXT: i32.const $push1=, 0{{$}}
+; CHECK-NEXT: i32.store $discard=, 42($pop0), $pop1{{$}}
define void @store_i32_to_numeric_address() {
%s = inttoptr i32 42 to i32*
store i32 0, i32* %s
@@ -275,8 +276,9 @@
}
; CHECK-LABEL: store_i32_to_global_address:
-; CHECK: i32.const $0=, 0{{$}}
-; CHECK: i32.store $discard=, gv($0), $0{{$}}
+; CHECK: i32.const $push0=, 0{{$}}
+; CHECK: i32.const $push1=, 0{{$}}
+; CHECK: i32.store $discard=, gv($pop0), $pop1{{$}}
define void @store_i32_to_global_address() {
store i32 0, i32* @gv
ret void
diff --git a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
index f8cae7f..8a9d399 100644
--- a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
+++ b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
@@ -52,24 +52,27 @@
; CHECK-LABEL: stack_uses:
; CHECK-NEXT: .param i32, i32, i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: .local i32, i32{{$}}
-; CHECK-NEXT: i32.const $5=, 2{{$}}
-; CHECK-NEXT: i32.const $4=, 1{{$}}
; CHECK-NEXT: block{{$}}
-; CHECK-NEXT: i32.lt_s $push0=, $0, $4{{$}}
-; CHECK-NEXT: i32.lt_s $push1=, $1, $5{{$}}
-; CHECK-NEXT: i32.xor $push4=, $pop0, $pop1{{$}}
-; CHECK-NEXT: i32.lt_s $push2=, $2, $4{{$}}
-; CHECK-NEXT: i32.lt_s $push3=, $3, $5{{$}}
-; CHECK-NEXT: i32.xor $push5=, $pop2, $pop3{{$}}
-; CHECK-NEXT: i32.xor $push6=, $pop4, $pop5{{$}}
-; CHECK-NEXT: i32.ne $push7=, $pop6, $4{{$}}
-; CHECK-NEXT: br_if $pop7, 0{{$}}
-; CHECK-NEXT: i32.const $push8=, 0{{$}}
-; CHECK-NEXT: return $pop8{{$}}
+; CHECK-NEXT: i32.const $push13=, 1{{$}}
+; CHECK-NEXT: i32.lt_s $push0=, $0, $pop13{{$}}
+; CHECK-NEXT: i32.const $push1=, 2{{$}}
+; CHECK-NEXT: i32.lt_s $push2=, $1, $pop1{{$}}
+; CHECK-NEXT: i32.xor $push5=, $pop0, $pop2{{$}}
+; CHECK-NEXT: i32.const $push12=, 1{{$}}
+; CHECK-NEXT: i32.lt_s $push3=, $2, $pop12{{$}}
+; CHECK-NEXT: i32.const $push11=, 2{{$}}
+; CHECK-NEXT: i32.lt_s $push4=, $3, $pop11{{$}}
+; CHECK-NEXT: i32.xor $push6=, $pop3, $pop4{{$}}
+; CHECK-NEXT: i32.xor $push7=, $pop5, $pop6{{$}}
+; CHECK-NEXT: i32.const $push10=, 1{{$}}
+; CHECK-NEXT: i32.ne $push8=, $pop7, $pop10{{$}}
+; CHECK-NEXT: br_if $pop8, 0{{$}}
+; CHECK-NEXT: i32.const $push9=, 0{{$}}
+; CHECK-NEXT: return $pop9{{$}}
; CHECK-NEXT: .LBB4_2:
; CHECK-NEXT: end_block{{$}}
-; CHECK-NEXT: return $4{{$}}
+; CHECK-NEXT: i32.const $push14=, 1{{$}}
+; CHECK-NEXT: return $pop14{{$}}
define i32 @stack_uses(i32 %x, i32 %y, i32 %z, i32 %w) {
entry:
%c = icmp sle i32 %x, 0
diff --git a/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll b/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll
index f6f5636..27e524b 100644
--- a/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll
+++ b/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll
@@ -8,10 +8,10 @@
; CHECK-LABEL: z2s_func:
; CHECK-NEXT: .param i32{{$}}
; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: .local i32{{$}}
-; CHECK-NEXT: i32.const $[[NUM0:[0-9]+]]=, 24{{$}}
-; CHECK-NEXT: i32.shl $push[[NUM2:[0-9]+]]=, $0, $[[NUM0]]{{$}}
-; CHECK-NEXT: i32.shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM0:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shl $push[[NUM2:[0-9]+]]=, $0, $pop[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM1:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $pop[[NUM1]]{{$}}
; CHECK-NEXT: return $pop[[NUM3]]{{$}}
define signext i8 @z2s_func(i8 zeroext %t) {
ret i8 %t
@@ -44,13 +44,15 @@
; CHECK-LABEL: s2z_call:
; CHECK-NEXT: .param i32{{$}}
; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: .local i32{{$}}
-; CHECK-NEXT: i32.const $[[NUM0:[0-9]+]]=, 24{{$}}
-; CHECK-NEXT: i32.shl $push[[NUM1:[0-9]+]]=, $0, $[[NUM0]]{{$}}
-; CHECK-NEXT: i32.shr_s $push[[NUM2:[0-9]+]]=, $pop[[NUM1]], $[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM0:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shl $push[[NUM1:[0-9]+]]=, $0, $pop[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM6:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shr_s $push[[NUM2:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM6]]{{$}}
; CHECK-NEXT: call $push[[NUM3:[0-9]]]=, s2z_func@FUNCTION, $pop[[NUM2]]{{$}}
-; CHECK-NEXT: i32.shl $push[[NUM4:[0-9]+]]=, $pop[[NUM3]], $[[NUM0]]{{$}}
-; CHECK-NEXT: i32.shr_s $push[[NUM5:[0-9]+]]=, $pop[[NUM4]], $[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM7:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shl $push[[NUM4:[0-9]+]]=, $pop[[NUM3]], $pop[[NUM7]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM8:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shr_s $push[[NUM5:[0-9]+]]=, $pop[[NUM4]], $pop[[NUM8]]{{$}}
; CHECK-NEXT: return $pop[[NUM5]]{{$}}
define i32 @s2z_call(i32 %t) {
%s = trunc i32 %t to i8
diff --git a/llvm/test/CodeGen/WebAssembly/store-results.ll b/llvm/test/CodeGen/WebAssembly/store-results.ll
index ae74133..5fa424a 100644
--- a/llvm/test/CodeGen/WebAssembly/store-results.ll
+++ b/llvm/test/CodeGen/WebAssembly/store-results.ll
@@ -26,7 +26,7 @@
@pos = global %class.Vec3 zeroinitializer, align 4
; CHECK-LABEL: foo:
-; CHECK: i32.store $discard=, pos($0), $0{{$}}
+; CHECK: i32.store $discard=, pos($pop{{[0-9]+}}), $pop{{[0-9]+}}{{$}}
define void @foo() {
for.body.i:
br label %for.body5.i
@@ -44,7 +44,7 @@
}
; CHECK-LABEL: bar:
-; CHECK: i32.store $discard=, pos($0), $0{{$}}
+; CHECK: i32.store $discard=, pos($pop{{[0-9]+}}), $pop{{[0-9]+}}{{$}}
define void @bar() {
for.body.i:
br label %for.body5.i