Skip to content

Commit 569083e

Browse files
committed
Merge branch 'feat/ts-core' into feat/ts-globals
2 parents b3e8746 + 42c87fe commit 569083e

61 files changed

Lines changed: 943 additions & 428 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

scripts/fuzz_opt.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -864,9 +864,11 @@ def can_run(self, wasm):
864864

865865
@override
866866
def can_compare_to_self(self):
867-
# With nans, VM differences can confuse us, so only very simple VMs
868-
# can compare to themselves after opts in that case.
869-
return not NANS
867+
# With nans or relaxed SIMD, VM differences can confuse us, including
868+
# differences between binaryen and V8 (binaryen's behavior can get
869+
# "baked" into the wasm when it precomputes code, so we cannot compare
870+
# V8's output before binaryen opts and after binaryen opts).
871+
return not NANS and all_disallowed(['relaxed-simd'])
870872

871873
@override
872874
def can_compare_to_other(self, other):
@@ -919,7 +921,7 @@ def can_run(self, wasm):
919921
if random.random() < 0.5:
920922
return False
921923
# wasm2c doesn't support most features
922-
return all_disallowed(['exception-handling', 'simd', 'threads', 'bulk-memory', 'nontrapping-float-to-int', 'tail-call', 'sign-ext', 'reference-types', 'multivalue', 'gc', 'custom-descriptors', 'relaxed-atomics', 'wide-arithmetic'])
924+
return all_disallowed(['exception-handling', 'simd', 'threads', 'bulk-memory', 'nontrapping-float-to-int', 'tail-call', 'sign-ext', 'reference-types', 'multivalue', 'gc', 'custom-descriptors', 'acquire-release-atomics', 'wide-arithmetic'])
923925

924926
@override
925927
def run(self, wasm):
@@ -1250,7 +1252,7 @@ def can_run_on_wasm(self, wasm):
12501252
# implement wasm suspending using JS async/await.
12511253
if JSPI:
12521254
return False
1253-
return all_disallowed(['exception-handling', 'simd', 'threads', 'bulk-memory', 'nontrapping-float-to-int', 'tail-call', 'sign-ext', 'reference-types', 'multivalue', 'gc', 'multimemory', 'memory64', 'custom-descriptors', 'relaxed-atomics', 'wide-arithmetic'])
1255+
return all_disallowed(['exception-handling', 'simd', 'threads', 'bulk-memory', 'nontrapping-float-to-int', 'tail-call', 'sign-ext', 'reference-types', 'multivalue', 'gc', 'multimemory', 'memory64', 'custom-descriptors', 'acquire-release-atomics', 'wide-arithmetic'])
12541256

12551257

12561258
# Returns the wat for a wasm file. If it is already wat, it just returns that
@@ -2048,10 +2050,11 @@ def handle(self, wasm):
20482050
compare(output, optimized_output, 'Two-Opt')
20492051

20502052
# If we can, also test in V8. We also cannot compare if there are NaNs
2051-
# (as optimizations can lead to different outputs), and we must
2052-
# disallow some features.
2053+
# or relaxed SIMD (as binaryen optimizations can lead to different
2054+
# outputs from V8), and we must disallow features that don't even work
2055+
# in V8.
20532056
# TODO: relax some of these
2054-
if NANS or not all_disallowed(DISALLOWED_FEATURES_IN_V8):
2057+
if NANS or not all_disallowed(['relaxed-simd']) or not all_disallowed(DISALLOWED_FEATURES_IN_V8):
20552058
return
20562059

20572060
output = run_d8_wasm(wasm, args=[second_wasm])

scripts/test/generate_atomic_spec_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def bin_statement_lines(template: Template, mem_idx: int, mem_ptr_type: ValueTyp
224224

225225
has_ordering = ordering is not None
226226
has_mem_idx = mem_idx is not None
227-
raw_alignment = int(math.log2(mem_ptr_type.value // 8))
227+
raw_alignment = int(math.log2(template.value_type.value // 8))
228228
alignment = raw_alignment | (has_ordering << 4) | (has_mem_idx << 6)
229229
comment = f"Alignment of {raw_alignment}" \
230230
f'{" with bit 4 set indicating that an ordering immediate follows" if has_ordering else ""}' \

src/binaryen-c.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,8 +505,8 @@ BinaryenFeatures BinaryenFeatureBulkMemoryOpt(void) {
505505
BinaryenFeatures BinaryenFeatureCallIndirectOverlong(void) {
506506
return static_cast<BinaryenFeatures>(FeatureSet::CallIndirectOverlong);
507507
}
508-
BinaryenFeatures BinaryenFeatureRelaxedAtomics(void) {
509-
return static_cast<BinaryenFeatures>(FeatureSet::RelaxedAtomics);
508+
BinaryenFeatures BinaryenFeatureAcquireReleaseAtomics(void) {
509+
return static_cast<BinaryenFeatures>(FeatureSet::AcquireReleaseAtomics);
510510
}
511511
BinaryenFeatures BinaryenFeatureMultibyte(void) {
512512
return static_cast<BinaryenFeatures>(FeatureSet::Multibyte);

src/binaryen-c.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ BINARYEN_API BinaryenFeatures BinaryenFeatureSharedEverything(void);
245245
BINARYEN_API BinaryenFeatures BinaryenFeatureFP16(void);
246246
BINARYEN_API BinaryenFeatures BinaryenFeatureBulkMemoryOpt(void);
247247
BINARYEN_API BinaryenFeatures BinaryenFeatureCallIndirectOverlong(void);
248-
BINARYEN_API BinaryenFeatures BinaryenFeatureRelaxedAtomics(void);
248+
BINARYEN_API BinaryenFeatures BinaryenFeatureAcquireReleaseAtomics(void);
249249
BINARYEN_API BinaryenFeatures BinaryenFeatureMultibyte(void);
250250
BINARYEN_API BinaryenFeatures BinaryenFeatureCustomPageSizes(void);
251251
BINARYEN_API BinaryenFeatures BinaryenFeatureWideArithmetic(void);

src/cfg/Relooper.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,6 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
333333
auto Base = std::string("switch$") + std::to_string(Id);
334334
auto SwitchDefault = wasm::Name(Base + "$default");
335335
auto SwitchLeave = wasm::Name(Base + "$leave");
336-
std::map<Block*, wasm::Name> BlockNameMap;
337336
auto* Outer = Builder.makeBlock();
338337
auto* Inner = Outer;
339338
std::vector<wasm::Name> Table;

src/compiler-support.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,10 @@
3131
#define WASM_BUILTIN_UNREACHABLE __assume(false)
3232
#endif
3333

34+
#if defined(__GNUC__) || defined(__clang__)
35+
#define BYN_WARN_UNUSED [[gnu::warn_unused]]
36+
#else
37+
#define BYN_WARN_UNUSED
38+
#endif
39+
3440
#endif // wasm_compiler_support_h

src/ir/constraint.cpp

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,17 @@ std::optional<Constraint> approximateOrTermEqualPair(const Abstract::Op aOp,
265265
if (aOp == Eq && bOp == GtS) {
266266
return Constraint{GeS, term};
267267
}
268+
if (aOp == Eq && bOp == GtU) {
269+
return Constraint{GeU, term};
270+
}
268271

269272
// x > C || x >= C === x >= C
270273
if (aOp == GtS && bOp == GeS) {
271274
return Constraint{GeS, term};
272275
}
276+
if (aOp == GtU && bOp == GeU) {
277+
return Constraint{GeU, term};
278+
}
273279

274280
// TODO: all the rest
275281

@@ -286,11 +292,17 @@ std::optional<Constraint> approximateOrAdjacentConstantPair(
286292
if (aOp == Eq && bOp == GeS && !aConstant.isSignedMax()) {
287293
return Constraint{GeS, {aConstant}};
288294
}
295+
if (aOp == Eq && bOp == GeU && !aConstant.isUnsignedMax()) {
296+
return Constraint{GeU, {aConstant}};
297+
}
289298

290299
// x > C || x >= C+1 === x > C, if C+1 does not overflow.
291300
if (aOp == GtS && bOp == GeS && !aConstant.isSignedMax()) {
292301
return Constraint{GtS, {aConstant}};
293302
}
303+
if (aOp == GtU && bOp == GeU && !aConstant.isUnsignedMax()) {
304+
return Constraint{GtU, {aConstant}};
305+
}
294306

295307
// TODO: all the rest
296308

@@ -494,15 +506,110 @@ void LocalConstraint::flip() {
494506
}
495507

496508
void BasicBlockConstraintMap::set(Index index, const Constraint& c) {
509+
set(index, AndedConstraintSet{c});
510+
}
511+
512+
void BasicBlockConstraintMap::set(Index index,
513+
const AndedConstraintSet& constraints) {
497514
// We should not set values in unreachable code.
498515
assert(!unreachable);
499516

500517
// Clear the old state.
501518
eraseStaleRefs(index);
502519
map.erase(index);
503520

504-
// Apply the constraint.
505-
approximateAnd(index, c);
521+
// Apply the constraints, if there are any.
522+
if (constraints.provesNothing()) {
523+
setProvesNothing(index);
524+
} else {
525+
for (auto& c : constraints) {
526+
approximateAnd(index, c);
527+
}
528+
}
529+
}
530+
531+
void BasicBlockConstraintMap::set(Index index, Expression* value) {
532+
using namespace Match;
533+
using namespace Abstract;
534+
535+
// Apply a constraint to a value, x = C.
536+
if (Properties::isSingleConstantExpression(value)) {
537+
auto c = Properties::getLiteral(value);
538+
set(index, Constraint{Abstract::Eq, {c}});
539+
return;
540+
}
541+
542+
// Apply a constraint to a local, x = y.
543+
if (auto* get = value->dynCast<LocalGet>()) {
544+
set(index, Constraint{Abstract::Eq, {get->index}});
545+
return;
546+
}
547+
548+
// Apply an increment of a local, x = y + 1.
549+
Index y;
550+
if (matches(value, binary(Abstract::Add, local(&y), ival(1)))) {
551+
// The local y must have old constraints that we know how to increment.
552+
auto old = get(y);
553+
554+
// Iterate over the old constraints and increment each one.
555+
auto success = true;
556+
for (auto& c : old) {
557+
auto* N = std::get_if<Literal>(&c.term);
558+
if (!N) {
559+
// A non-constant term, which we don't know how to increment.
560+
success = false;
561+
break;
562+
}
563+
564+
switch (c.op) {
565+
// x == N, x++ => x == N+1.
566+
case Eq:
567+
*N = N->add(Literal::makeFromInt32(1, N->type));
568+
continue;
569+
// x >= N, x++ => x > N
570+
case GeS:
571+
c.op = GtS;
572+
continue;
573+
case GeU:
574+
c.op = GtU;
575+
continue;
576+
// x < N, x++ => x <= N
577+
case LtS:
578+
c.op = LeS;
579+
continue;
580+
case LtU:
581+
c.op = LeU;
582+
continue;
583+
// x <= N, x++ => x <= N+1 if no overflow
584+
case LeS:
585+
if (N->isSignedMax()) {
586+
success = false;
587+
break;
588+
}
589+
*N = N->add(Literal::makeFromInt32(1, N->type));
590+
continue;
591+
case LeU:
592+
if (N->isUnsignedMax()) {
593+
success = false;
594+
break;
595+
}
596+
*N = N->add(Literal::makeFromInt32(1, N->type));
597+
continue;
598+
default:
599+
// Something we don't recognize.
600+
success = false;
601+
break;
602+
}
603+
}
604+
605+
if (success) {
606+
set(index, old);
607+
return;
608+
}
609+
}
610+
611+
// We know and can prove nothing.
612+
setProvesNothing(index);
506613
}
507614

508615
void BasicBlockConstraintMap::setProvesNothing(Index index) {

src/ir/constraint.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,15 @@ struct BasicBlockConstraintMap {
251251
assert(map.empty());
252252
}
253253

254-
// Apply a constraint to a local.
254+
// Apply a constraint to a local, replacing anything before.
255255
void set(Index index, const Constraint& c);
256256

257+
// Apply a set of constraints to a local, replacing anything before.
258+
void set(Index index, const AndedConstraintSet& constraints);
259+
260+
// Set the value in an expression to a local, replacing anything before.
261+
void set(Index index, Expression* value);
262+
257263
// Mark a local as unknown and able to prove nothing.
258264
void setProvesNothing(Index index);
259265

src/ir/effects.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,10 +1044,8 @@ class EffectAnalyzer {
10441044
}
10451045
void visitRefGetDesc(RefGetDesc* curr) { trapOnNull(curr->ref); }
10461046
void visitBrOn(BrOn* curr) {
1047-
if (trapOnNull(curr->desc)) {
1048-
return;
1049-
}
10501047
parent.breakTargets.insert(curr->name);
1048+
trapOnNull(curr->desc);
10511049
}
10521050
void visitStructNew(StructNew* curr) { trapOnNull(curr->desc); }
10531051
void visitStructGet(StructGet* curr) {

src/ir/features.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ inline FeatureSet get(BinaryOp op) {
173173
case RelaxedMinVecF64x2:
174174
case RelaxedMaxVecF64x2:
175175
case RelaxedSwizzleVecI8x16:
176-
case RelaxedQ15MulrSVecI16x8: {
176+
case RelaxedQ15MulrSVecI16x8:
177+
case RelaxedDotI8x16I7x16SToVecI16x8: {
177178
ret.setSIMD();
178179
ret.setRelaxedSIMD();
179180
break;

0 commit comments

Comments
 (0)