summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md5
-rw-r--r--src/wasm/wasm-emscripten.cpp49
-rw-r--r--test/lld/em_asm_O0.wast.out8
-rw-r--r--test/lld/em_asm_shared.wast.out17
4 files changed, 40 insertions, 39 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 56672f8e9..a6885ed13 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,11 @@ full changeset diff at the end of each section.
Current Trunk
-------------
+v81
+---
+
+- Fix AsmConstWalker handling of string address in arg0 with -fPIC code
+
v80
---
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 837dcbea1..680e145b4 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -525,30 +525,37 @@ void AsmConstWalker::visitCall(Call* curr) {
auto baseSig = getSig(curr);
auto sig = fixupNameWithSig(curr->target, baseSig);
auto* arg = curr->operands[0];
- if (auto* get = arg->dynCast<GetLocal>()) {
- // The argument may be a local.get, in which case, the last set in this
- // basic block has the value.
- auto* set = sets[get->index];
- if (set) {
- assert(set->index == get->index);
- arg = set->value;
- }
- } else if (auto* value = arg->dynCast<Binary>()) {
- // In the dynamic linking case the address of the string constant
- // is the result of adding its offset to __memory_base.
- // In this case are only looking for the offset with the data segment so
- // the RHS of the addition is just what we want.
- assert(value->op == AddInt32);
- arg = value->right;
- }
-
- auto* value = arg->dynCast<Const>();
- if (!value)
- Fatal() << "Unexpected arg0 type (" << getExpressionName(arg)
+ while (!arg->dynCast<Const>()) {
+ if (auto* get = arg->dynCast<GetLocal>()) {
+ // The argument may be a local.get, in which case, the last set in this
+ // basic block has the value.
+ auto* set = sets[get->index];
+ if (set) {
+ assert(set->index == get->index);
+ arg = set->value;
+ }
+ } else if (auto* value = arg->dynCast<Binary>()) {
+ // In the dynamic linking case the address of the string constant
+ // is the result of adding its offset to __memory_base.
+ // In this case are only looking for the offset with the data segment so
+ // the RHS of the addition is just what we want.
+ assert(value->op == AddInt32);
+ arg = value->right;
+ } else {
+ if (!value) {
+ Fatal() << "Unexpected arg0 type (" << getExpressionName(arg)
<< ") in call to to: " << import->base;
+ }
+ }
+ }
+
+ auto* value = arg->cast<Const>();
auto code = codeForConstAddr(wasm, segmentOffsets, value);
- value->value = idLiteralForCode(code);
sigsForCode[code].insert(sig);
+
+ // Replace the first argument to the call with a Const index
+ Builder builder(wasm);
+ curr->operands[0] = builder.makeConst(idLiteralForCode(code));
}
}
diff --git a/test/lld/em_asm_O0.wast.out b/test/lld/em_asm_O0.wast.out
index d194c8185..cb5cc1961 100644
--- a/test/lld/em_asm_O0.wast.out
+++ b/test/lld/em_asm_O0.wast.out
@@ -34,16 +34,16 @@
)
)
(local.set $t1
- (i32.const 2)
+ (i32.const 621)
)
(local.set $t2
- (i32.const 1)
+ (i32.const 601)
)
(drop
(call $emscripten_asm_const_ii
- (local.get $t1)
+ (i32.const 2)
(call $emscripten_asm_const_iii
- (local.get $t2)
+ (i32.const 1)
(i32.const 13)
(i32.const 27)
)
diff --git a/test/lld/em_asm_shared.wast.out b/test/lld/em_asm_shared.wast.out
index 220a10aca..3a5268380 100644
--- a/test/lld/em_asm_shared.wast.out
+++ b/test/lld/em_asm_shared.wast.out
@@ -48,12 +48,7 @@
)
(drop
(call $emscripten_asm_const_iii
- (i32.add
- (local.tee $1
- (global.get $gimport$3)
- )
- (i32.const 0)
- )
+ (i32.const 0)
(i32.add
(local.get $0)
(i32.const 24)
@@ -80,10 +75,7 @@
)
(local.tee $2
(call $emscripten_asm_const_iii
- (i32.add
- (local.get $1)
- (i32.const 1)
- )
+ (i32.const 1)
(i32.add
(local.get $0)
(i32.const 24)
@@ -101,10 +93,7 @@
)
(drop
(call $emscripten_asm_const_iii
- (i32.add
- (local.get $1)
- (i32.const 2)
- )
+ (i32.const 2)
(i32.add
(local.get $0)
(i32.const 24)