Skip to content

Commit a1afe47

Browse files
authored
Fuzzer: Separate arguments used to make the fuzz wasm from the opts we run on it (#6357)
Before FUZZ_OPTS was used both when doing --translate-to-fuzz/-ttf to generate the wasm from the random bytes and also when later running optimizations to generate a second wasm file for comparison. That is, we ended up doing this, if the opts were -O3: wasm-opt random.input -ttf -o a.wasm -O3 wasm-opt a.wasm -O3 -o b.wasm Now we have a pair a.wasm,b.wasm which we can test. However, we have run -O3 on both which is a little silly - the second -O3 might not actually have anything left to do, which would mean we compare the same wasm to itself. Worse, this is incorrect, as there are things we need to do only during the generation phase, like --denan. We need that in order to generate a valid wasm to test on, but it is "destructive" in itself: when removing NaNs (to avoid nondeterminism) if replaces them with 0, which is different. As a result, running --denan when generating the second wasm from the first could lead to different execution in them. This was always a problem, but became more noticable recently now that DeNaN modifies SIMD operations, as one optimization we do is to replace a memory.copy with v128.load + v128.store, and --denan will make sure the loaded value has no NaNs... To fix this, separate the generation and optimization phase. Instead of wasm-opt random.input -ttf -o a.wasm --denan -O3 wasm-opt a.wasm --denan -O3 -o b.wasm (note how --denan -O3 appears twice), do this: wasm-opt random.input -ttf -o a.wasm --denan wasm-opt a.wasm -O3 -o b.wasm (note how --denan appears in generation, and -O3 in optimization).
1 parent d5157e0 commit a1afe47

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

scripts/fuzz_opt.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,13 @@ def update_feature_opts(wasm):
174174

175175

176176
def randomize_fuzz_settings():
177+
# a list of the arguments to pass to wasm-opt -ttf when generating the wasm
178+
global GEN_ARGS
179+
GEN_ARGS = []
180+
177181
# a list of the optimizations to run on the wasm
178182
global FUZZ_OPTS
183+
FUZZ_OPTS = []
179184

180185
# a boolean whether NaN values are allowed, or we de-NaN them
181186
global NANS
@@ -186,20 +191,19 @@ def randomize_fuzz_settings():
186191
# a boolean whether we legalize the wasm for JS
187192
global LEGALIZE
188193

189-
FUZZ_OPTS = []
190194
if random.random() < 0.5:
191195
NANS = True
192196
else:
193197
NANS = False
194-
FUZZ_OPTS += ['--denan']
198+
GEN_ARGS += ['--denan']
195199
if random.random() < 0.5:
196200
OOB = True
197201
else:
198202
OOB = False
199-
FUZZ_OPTS += ['--no-fuzz-oob']
203+
GEN_ARGS += ['--no-fuzz-oob']
200204
if random.random() < 0.5:
201205
LEGALIZE = True
202-
FUZZ_OPTS += ['--legalize-and-prune-js-interface']
206+
GEN_ARGS += ['--legalize-and-prune-js-interface']
203207
else:
204208
LEGALIZE = False
205209

@@ -209,6 +213,10 @@ def randomize_fuzz_settings():
209213
# https://github.com/WebAssembly/binaryen/pull/5665
210214
# https://github.com/WebAssembly/binaryen/issues/5599
211215
if '--disable-gc' not in FEATURE_OPTS:
216+
GEN_ARGS += ['--dce']
217+
218+
# Add --dce not only when generating the original wasm but to the
219+
# optimizations we use to create any other wasm file.
212220
FUZZ_OPTS += ['--dce']
213221

214222
print('randomized settings (NaNs, OOB, legalize):', NANS, OOB, LEGALIZE)
@@ -1267,7 +1275,7 @@ def handle(self, wasm):
12671275
second_input = abspath('second_input.dat')
12681276
make_random_input(second_size, second_input)
12691277
second_wasm = abspath('second.wasm')
1270-
run([in_bin('wasm-opt'), second_input, '-ttf', '-o', second_wasm] + FUZZ_OPTS + FEATURE_OPTS)
1278+
run([in_bin('wasm-opt'), second_input, '-ttf', '-o', second_wasm] + GEN_ARGS + FEATURE_OPTS)
12711279

12721280
# sometimes also optimize the second module
12731281
if random.random() < 0.5:
@@ -1364,14 +1372,14 @@ def test_one(random_input, given_wasm):
13641372
# wasm had applied. that is, we need to preserve properties like not
13651373
# having nans through reduction.
13661374
try:
1367-
run([in_bin('wasm-opt'), given_wasm, '-o', abspath('a.wasm')] + FUZZ_OPTS + FEATURE_OPTS)
1375+
run([in_bin('wasm-opt'), given_wasm, '-o', abspath('a.wasm')] + GEN_ARGS + FEATURE_OPTS)
13681376
except Exception as e:
13691377
print("Internal error in fuzzer! Could not run given wasm")
13701378
raise e
13711379
else:
13721380
# emit the target features section so that reduction can work later,
13731381
# without needing to specify the features
1374-
generate_command = [in_bin('wasm-opt'), random_input, '-ttf', '-o', abspath('a.wasm')] + FUZZ_OPTS + FEATURE_OPTS
1382+
generate_command = [in_bin('wasm-opt'), random_input, '-ttf', '-o', abspath('a.wasm')] + GEN_ARGS + FEATURE_OPTS
13751383
if INITIAL_CONTENTS:
13761384
generate_command += ['--initial-fuzz=' + INITIAL_CONTENTS]
13771385
if PRINT_WATS:
@@ -1385,7 +1393,7 @@ def test_one(random_input, given_wasm):
13851393
print('pre wasm size:', wasm_size)
13861394
update_feature_opts('a.wasm')
13871395

1388-
# create a second wasm for handlers that want to look at pairs.
1396+
# create a second (optimized) wasm for handlers that want to look at pairs.
13891397
generate_command = [in_bin('wasm-opt'), abspath('a.wasm'), '-o', abspath('b.wasm')] + opts + FUZZ_OPTS + FEATURE_OPTS
13901398
if PRINT_WATS:
13911399
printed = run(generate_command + ['--print'])

0 commit comments

Comments
 (0)