Skip to content

Commit de15161

Browse files
authored
Merge pull request #1119 from WebAssembly/fuzz-2
More fun fuzz fixes
2 parents 5a07a93 + 6d686bd commit de15161

10 files changed

Lines changed: 199 additions & 19 deletions

src/ast/bits.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ struct Bits {
5151
WASM_UNREACHABLE();
5252
}
5353

54-
static Index getEffectiveShifts(Const* amount) {
54+
static Index getEffectiveShifts(Expression* expr) {
55+
auto* amount = expr->cast<Const>();
5556
if (amount->type == i32) {
5657
return getEffectiveShifts(amount->value.geti32(), i32);
5758
} else if (amount->type == i64) {

src/ast/properties.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ struct Properties {
7979

8080
// gets the size of the sign-extended value
8181
static Index getSignExtBits(Expression* curr) {
82-
return 32 - curr->cast<Binary>()->right->cast<Const>()->value.geti32();
82+
return 32 - Bits::getEffectiveShifts(curr->cast<Binary>()->right);
8383
}
8484

8585
// Check if an expression is almost a sign-extend: perhaps the inner shift
@@ -93,7 +93,7 @@ struct Properties {
9393
if (auto* inner = outer->left->dynCast<Binary>()) {
9494
if (inner->op == ShlInt32) {
9595
if (auto* innerConst = inner->right->dynCast<Const>()) {
96-
if (outerConst->value.leU(innerConst->value).geti32()) {
96+
if (Bits::getEffectiveShifts(outerConst) <= Bits::getEffectiveShifts(innerConst)) {
9797
return inner->left;
9898
}
9999
}
@@ -109,8 +109,8 @@ struct Properties {
109109
// gets the size of the almost sign-extended value, as well as the
110110
// extra shifts, if any
111111
static Index getAlmostSignExtBits(Expression* curr, Index& extraShifts) {
112-
extraShifts = curr->cast<Binary>()->left->cast<Binary>()->right->cast<Const>()->value.geti32() -
113-
curr->cast<Binary>()->right->cast<Const>()->value.geti32();
112+
extraShifts = Bits::getEffectiveShifts(curr->cast<Binary>()->left->cast<Binary>()->right) -
113+
Bits::getEffectiveShifts(curr->cast<Binary>()->right);
114114
return getSignExtBits(curr);
115115
}
116116

src/passes/OptimizeInstructions.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,8 @@ Index getMaxBits(Expression* curr, LocalInfoProvider* localInfoProvider) {
228228
}
229229
} else if (auto* unary = curr->dynCast<Unary>()) {
230230
switch (unary->op) {
231-
case ClzInt32: case CtzInt32: case PopcntInt32: return 5;
232-
case ClzInt64: case CtzInt64: case PopcntInt64: return 6;
231+
case ClzInt32: case CtzInt32: case PopcntInt32: return 6;
232+
case ClzInt64: case CtzInt64: case PopcntInt64: return 7;
233233
case EqZInt32: case EqZInt64: return 1;
234234
case WrapInt64: return std::min(Index(32), getMaxBits(unary->value, localInfoProvider));
235235
default: {}
@@ -779,7 +779,7 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
779779
return;
780780
} else if (binary->op == ShlInt32) {
781781
if (auto* c = binary->right->dynCast<Const>()) {
782-
seek(binary->left, mul * Pow2(c->value.geti32()));
782+
seek(binary->left, mul * Pow2(Bits::getEffectiveShifts(c)));
783783
return;
784784
}
785785
} else if (binary->op == MulInt32) {
@@ -836,7 +836,7 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
836836
}
837837
} else if (curr->op == ShlInt32) {
838838
// shifting a 0 is a 0, unless the shift has side effects
839-
if (left && left->value.geti32() == 0 && !EffectAnalyzer(passOptions, curr->right).hasSideEffects()) {
839+
if (left && Bits::getEffectiveShifts(left) == 0 && !EffectAnalyzer(passOptions, curr->right).hasSideEffects()) {
840840
replaceCurrent(left);
841841
return;
842842
}

src/wasm/wasm-binary.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,14 @@ void WasmBinaryWriter::visitSwitch(Switch *curr) {
666666
recurse(curr->value);
667667
}
668668
recurse(curr->condition);
669+
if (!BranchUtils::isBranchTaken(curr)) {
670+
// if the branch is not taken, then it's dangerous to emit it, as
671+
// wasm type checking rules are stricter than ours - we tolerate
672+
// an untaken branch to a target with a different value, but not
673+
// wasm. so just don't emit it
674+
o << int8_t(BinaryConsts::Unreachable);
675+
return;
676+
}
669677
o << int8_t(BinaryConsts::TableSwitch) << U32LEB(curr->targets.size());
670678
for (auto target : curr->targets) {
671679
o << U32LEB(getBreakIndex(target));
@@ -1796,7 +1804,7 @@ void WasmBinaryBuilder::processExpressions() { // until an end or else marker, o
17961804

17971805
Expression* WasmBinaryBuilder::popExpression() {
17981806
if (expressionStack.empty()) {
1799-
throw ParseException("attempted pop from empty stack");
1807+
throw ParseException("attempted pop from empty stack at " + std::to_string(pos));
18001808
}
18011809
auto ret = expressionStack.back();
18021810
// to simulate the wasm polymorphic stack mode, leave a final

test/passes/optimize-instructions.txt

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
(type $5 (func (param i32)))
88
(type $6 (func (param i32 i32) (result i32)))
99
(type $7 (func (param i64) (result i64)))
10+
(type $8 (func (result i64)))
1011
(memory $0 0)
1112
(export "load-off-2" (func $load-off-2))
1213
(func $f (type $0) (param $i1 i32) (param $i2 i64)
@@ -827,11 +828,14 @@
827828
)
828829
)
829830
(drop
830-
(i32.shl
831-
(i32.clz
832-
(i32.const 0)
831+
(i32.shr_s
832+
(i32.shl
833+
(i32.clz
834+
(i32.const 0)
835+
)
836+
(i32.const 26)
833837
)
834-
(i32.const 2)
838+
(i32.const 24)
835839
)
836840
)
837841
(drop
@@ -853,13 +857,16 @@
853857
)
854858
)
855859
(drop
856-
(i32.shl
857-
(i32.wrap/i64
858-
(i64.clz
859-
(i64.const 0)
860+
(i32.shr_s
861+
(i32.shl
862+
(i32.wrap/i64
863+
(i64.clz
864+
(i64.const 0)
865+
)
860866
)
867+
(i32.const 25)
861868
)
862-
(i32.const 1)
869+
(i32.const 24)
863870
)
864871
)
865872
(drop
@@ -2061,4 +2068,56 @@
20612068
(i32.const 9)
20622069
)
20632070
)
2071+
(func $mix-shifts (type $2) (result i32)
2072+
(i32.shr_s
2073+
(i32.shl
2074+
(i32.const 23)
2075+
(i32.const -61)
2076+
)
2077+
(i32.const 168)
2078+
)
2079+
)
2080+
(func $actually-no-shifts (type $2) (result i32)
2081+
(i32.const 33)
2082+
)
2083+
(func $less-shifts-than-it-seems (type $3) (param $x i32) (result i32)
2084+
(i32.const 4800)
2085+
)
2086+
(func $and-popcount32 (type $2) (result i32)
2087+
(i32.and
2088+
(i32.popcnt
2089+
(i32.const -1)
2090+
)
2091+
(i32.const 31)
2092+
)
2093+
)
2094+
(func $and-popcount32-big (type $2) (result i32)
2095+
(i32.popcnt
2096+
(i32.const -1)
2097+
)
2098+
)
2099+
(func $and-popcount64 (type $8) (result i64)
2100+
(i64.and
2101+
(i64.popcnt
2102+
(i64.const -1)
2103+
)
2104+
(i64.const 63)
2105+
)
2106+
)
2107+
(func $and-popcount64-big (type $8) (result i64)
2108+
(i64.and
2109+
(i64.popcnt
2110+
(i64.const -1)
2111+
)
2112+
(i64.const 127)
2113+
)
2114+
)
2115+
(func $and-popcount64-bigger (type $8) (result i64)
2116+
(i64.and
2117+
(i64.popcnt
2118+
(i64.const -1)
2119+
)
2120+
(i64.const 255)
2121+
)
2122+
)
20642123
)

test/passes/optimize-instructions.wast

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,4 +2496,74 @@
24962496
(i32.const 4098) ;; 2 bits effectively
24972497
)
24982498
)
2499+
(func $mix-shifts (result i32)
2500+
(i32.shr_s
2501+
(i32.shl
2502+
(i32.const 23)
2503+
(i32.const -61)
2504+
)
2505+
(i32.const 168)
2506+
)
2507+
)
2508+
(func $actually-no-shifts (result i32)
2509+
(i32.add
2510+
(i32.shl
2511+
(i32.const 23)
2512+
(i32.const 32) ;; really 0
2513+
)
2514+
(i32.const 10)
2515+
)
2516+
)
2517+
(func $less-shifts-than-it-seems (param $x i32) (result i32)
2518+
(i32.add
2519+
(i32.shl
2520+
(i32.const 200)
2521+
(i32.const 36) ;; really 4
2522+
)
2523+
(i32.shl
2524+
(i32.const 100)
2525+
(i32.const 4)
2526+
)
2527+
)
2528+
)
2529+
(func $and-popcount32 (result i32)
2530+
(i32.and
2531+
(i32.popcnt
2532+
(i32.const -1)
2533+
)
2534+
(i32.const 31)
2535+
)
2536+
)
2537+
(func $and-popcount32-big (result i32)
2538+
(i32.and
2539+
(i32.popcnt
2540+
(i32.const -1)
2541+
)
2542+
(i32.const 63)
2543+
)
2544+
)
2545+
(func $and-popcount64 (result i64) ;; these are TODOs
2546+
(i64.and
2547+
(i64.popcnt
2548+
(i64.const -1)
2549+
)
2550+
(i64.const 63)
2551+
)
2552+
)
2553+
(func $and-popcount64-big (result i64)
2554+
(i64.and
2555+
(i64.popcnt
2556+
(i64.const -1)
2557+
)
2558+
(i64.const 127)
2559+
)
2560+
)
2561+
(func $and-popcount64-bigger (result i64)
2562+
(i64.and
2563+
(i64.popcnt
2564+
(i64.const -1)
2565+
)
2566+
(i64.const 255)
2567+
)
2568+
)
24992569
)

test/polymorphic_stack.wast

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,15 @@
8686
)
8787
)
8888
)
89+
(func $br_table_unreachable_to_also_unreachable (result i32)
90+
(block $a (result i32)
91+
(block $b
92+
(br_table $a $b ;; seems to send a value, but is not taken
93+
(unreachable)
94+
(unreachable)
95+
)
96+
)
97+
)
98+
)
8999
)
90100

test/polymorphic_stack.wast.from-wast

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,14 @@
9090
)
9191
)
9292
)
93+
(func $br_table_unreachable_to_also_unreachable (type $1) (result i32)
94+
(block $a (result i32)
95+
(block $b
96+
(br_table $a $b
97+
(unreachable)
98+
(unreachable)
99+
)
100+
)
101+
)
102+
)
93103
)

test/polymorphic_stack.wast.fromBinary

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,16 @@
125125
(unreachable)
126126
)
127127
)
128+
(func $br_table_unreachable_to_also_unreachable (type $1) (result i32)
129+
(block $label$0 (result i32)
130+
(block $label$1
131+
(unreachable)
132+
(unreachable)
133+
(unreachable)
134+
(unreachable)
135+
)
136+
(unreachable)
137+
)
138+
)
128139
)
129140

test/polymorphic_stack.wast.fromBinary.noDebugInfo

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,16 @@
125125
(unreachable)
126126
)
127127
)
128+
(func $6 (type $1) (result i32)
129+
(block $label$0 (result i32)
130+
(block $label$1
131+
(unreachable)
132+
(unreachable)
133+
(unreachable)
134+
(unreachable)
135+
)
136+
(unreachable)
137+
)
138+
)
128139
)
129140

0 commit comments

Comments
 (0)