;; RUN: wasm-reduce --help | filecheck %s
;; CHECK: ================================================================================
;; CHECK-NEXT: wasm-reduce INFILE
;; CHECK-NEXT:
;; CHECK-NEXT: Reduce a wasm file to a smaller one with the same behavior on a given command.
;; CHECK-NEXT:
;; CHECK-NEXT: Typical usage:
;; CHECK-NEXT:
;; CHECK-NEXT:   wasm-reduce orig.wasm '--command=bash a.sh' --test t.wasm --working w.wasm
;; CHECK-NEXT:
;; CHECK-NEXT: The original file orig.wasm is where we begin. We then repeatedly test a small
;; CHECK-NEXT: reduction of it by writing that modification to the 'test file' (specified by
;; CHECK-NEXT: '--test'), and we run the command, in this example 'bash a.sh'. That command
;; CHECK-NEXT: should use the test file (and not the original file or any other one). Whenever
;; CHECK-NEXT: the reduction works, we write that new smaller file to the 'working file'
;; CHECK-NEXT: (specified by '--working'). The reduction 'works' if it correctly preserves the
;; CHECK-NEXT: behavior of the command on the original input, specifically, that it has the
;; CHECK-NEXT: same stdout and the result return code. Each time reduction works we continue to
;; CHECK-NEXT: reduce from that point (and each time it fails, we go back and try something
;; CHECK-NEXT: else).
;; CHECK-NEXT:
;; CHECK-NEXT: As mentioned above, the command should run on the test file. That is, the first
;; CHECK-NEXT: thing that wasm-reduce does on the example above is, effectively,
;; CHECK-NEXT:
;; CHECK-NEXT:   cp orig.wasm t.wasm
;; CHECK-NEXT:   bash a.sh
;; CHECK-NEXT:
;; CHECK-NEXT: In other words, it copies the original to the test file, and runs the command.
;; CHECK-NEXT: Whatever the command does, we will preserve as we copy progressively smaller
;; CHECK-NEXT: files to t.wasm. As we make progress, the smallest file will be written to
;; CHECK-NEXT: the working file, w.wasm, and when reduction is done you will find the final
;; CHECK-NEXT: result there.
;; CHECK-NEXT:
;; CHECK-NEXT: Comparison to creduce:
;; CHECK-NEXT:
;; CHECK-NEXT: 1. creduce requires the command to return 0. wasm-reduce is often used to reduce
;; CHECK-NEXT:    crashes, which have non-zero return codes, so it is natural to allow any
;; CHECK-NEXT:    return code. As mentioned above, we preserve the return code as we reduce.
;; CHECK-NEXT: 2. creduce ignores stdout. wasm-reduce preserves stdout as it reduces, as part
;; CHECK-NEXT:    of the principle of preserving the original behavior of the command (if your
;; CHECK-NEXT:    stdout varies in uninteresting ways, your command can be a script that runs
;; CHECK-NEXT:    the real command and captures stdout to /dev/null, or filters it).
;; CHECK-NEXT: 3. creduce tramples the original input file as it reduces. wasm-reduce never
;; CHECK-NEXT:    modifies the input (to avoid mistakes that cause data loss). Instead,
;; CHECK-NEXT:    when reductions work we write to the 'working file' as mentioned above, and
;; CHECK-NEXT:    the final reduction will be there.
;; CHECK-NEXT: 4. creduce runs the command in a temp directory. That is safer in general, but
;; CHECK-NEXT:    it is not how the original command ran, and in particular forces additional
;; CHECK-NEXT:    work if you have multiple files (which, for wasm-reduce, is common, e.g. if
;; CHECK-NEXT:    the testcase is a combination of JavaScript and wasm). wasm-reduce runs the
;; CHECK-NEXT:    command in the current directory (of course, your command can be a script
;; CHECK-NEXT:    that changes directory to anywhere else).
;; CHECK-NEXT:
;; CHECK-NEXT: More documentation can be found at
;; CHECK-NEXT:
;; CHECK-NEXT:   https://github.com/WebAssembly/binaryen/wiki/Fuzzing#reducing
;; CHECK-NEXT:
;; CHECK-NEXT: ================================================================================
;; CHECK-NEXT:
;; CHECK-NEXT:
;; CHECK-NEXT: wasm-reduce options:
;; CHECK-NEXT: --------------------
;; CHECK-NEXT:
;; CHECK-NEXT:   --command,-cmd                       The command to run on the test, that we
;; CHECK-NEXT:                                        want to reduce while keeping the
;; CHECK-NEXT:                                        command's output identical. We look at
;; CHECK-NEXT:                                        the command's return code and stdout here
;; CHECK-NEXT:                                        (TODO: stderr), and we reduce while
;; CHECK-NEXT:                                        keeping those unchanged.
;; CHECK-NEXT:
;; CHECK-NEXT:   --test,-t                            Test file (this will be written to test,
;; CHECK-NEXT:                                        the given command should read it when we
;; CHECK-NEXT:                                        call it)
;; CHECK-NEXT:
;; CHECK-NEXT:   --working,-w                         Working file (this will contain the
;; CHECK-NEXT:                                        current good state while doing temporary
;; CHECK-NEXT:                                        computations, and will contain the final
;; CHECK-NEXT:                                        best result at the end)
;; CHECK-NEXT:
;; CHECK-NEXT:   --binaries,-b                        binaryen binaries location (bin/
;; CHECK-NEXT:                                        directory)
;; CHECK-NEXT:
;; CHECK-NEXT:   --text,-S                            Emit intermediate files as text, instead
;; CHECK-NEXT:                                        of binary (also make sure the test and
;; CHECK-NEXT:                                        working files have a .wat or .wast
;; CHECK-NEXT:                                        suffix)
;; CHECK-NEXT:
;; CHECK-NEXT:   --denan                              Avoid nans when reducing
;; CHECK-NEXT:
;; CHECK-NEXT:   --verbose,-v                         Verbose output mode
;; CHECK-NEXT:
;; CHECK-NEXT:   --debugInfo,-g                       Keep debug info in binaries
;; CHECK-NEXT:
;; CHECK-NEXT:   --force,-f                           Force the reduction attempt, ignoring
;; CHECK-NEXT:                                        problems that imply it is unlikely to
;; CHECK-NEXT:                                        succeed
;; CHECK-NEXT:
;; CHECK-NEXT:   --timeout,-to                        A timeout to apply to each execution of
;; CHECK-NEXT:                                        the command, in seconds (default: 2)
;; CHECK-NEXT:
;; CHECK-NEXT:   --extra-flags,-ef                    Extra commandline flags to pass to
;; CHECK-NEXT:                                        wasm-opt while reducing. (default:
;; CHECK-NEXT:                                        --enable-all)
;; CHECK-NEXT:
;; CHECK-NEXT:   --save-all-working,-saw              Save all intermediate working files, as
;; CHECK-NEXT:                                        $WORKING.0, .1, .2 etc
;; CHECK-NEXT:
;; CHECK-NEXT:
;; CHECK-NEXT: Tool options:
;; CHECK-NEXT: -------------
;; CHECK-NEXT:
;; CHECK-NEXT:   --mvp-features,-mvp                  Disable all non-MVP features
;; CHECK-NEXT:
;; CHECK-NEXT:   --all-features,-all                  Enable all features
;; CHECK-NEXT:
;; CHECK-NEXT:   --detect-features                    (deprecated - this flag does nothing)
;; CHECK-NEXT:
;; CHECK-NEXT:   --quiet,-q                           Emit less verbose output and hide trivial
;; CHECK-NEXT:                                        warnings.
;; CHECK-NEXT:
;; CHECK-NEXT:   --experimental-poppy                 Parse wast files as Poppy IR for testing
;; CHECK-NEXT:                                        purposes.
;; CHECK-NEXT:
;; CHECK-NEXT:   --emit-module-names                  Emit module names, even if not emitting
;; CHECK-NEXT:                                        the rest of the names section
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-sign-ext                    Enable sign extension operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-sign-ext                   Disable sign extension operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-threads                     Enable atomic operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-threads                    Disable atomic operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-mutable-globals             Enable mutable globals
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-mutable-globals            Disable mutable globals
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-nontrapping-float-to-int    Enable nontrapping float-to-int
;; CHECK-NEXT:                                        operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-nontrapping-float-to-int   Disable nontrapping float-to-int
;; CHECK-NEXT:                                        operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-simd                        Enable SIMD operations and types
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-simd                       Disable SIMD operations and types
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-bulk-memory                 Enable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-bulk-memory                Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-bulk-memory-opt             Enable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-bulk-memory-opt            Disable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-call-indirect-overlong      Enable LEB encoding of call-indirect
;; CHECK-NEXT:                                        (Ignored for compatibility as it has no
;; CHECK-NEXT:                                        effect on Binaryen)
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-call-indirect-overlong     Disable LEB encoding of call-indirect
;; CHECK-NEXT:                                        (Ignored for compatibility as it has no
;; CHECK-NEXT:                                        effect on Binaryen)
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-exception-handling          Enable exception handling operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-exception-handling         Disable exception handling operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-tail-call                   Enable tail call operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-tail-call                  Disable tail call operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-reference-types             Enable reference types
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-reference-types            Disable reference types
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-multivalue                  Enable multivalue functions
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-multivalue                 Disable multivalue functions
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-gc                          Enable garbage collection
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-gc                         Disable garbage collection
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-memory64                    Enable memory64
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-memory64                   Disable memory64
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-relaxed-simd                Enable relaxed SIMD
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-relaxed-simd               Disable relaxed SIMD
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-extended-const              Enable extended const expressions
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-extended-const             Disable extended const expressions
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-strings                     Enable strings
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-strings                    Disable strings
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-multimemory                 Enable multimemory
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-multimemory                Disable multimemory
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-stack-switching             Enable stack switching
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-stack-switching            Disable stack switching
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-shared-everything           Enable shared-everything threads
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-shared-everything          Disable shared-everything threads
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-fp16                        Enable float 16 operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-fp16                       Disable float 16 operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-custom-descriptors          Enable custom descriptors (RTTs) and
;; CHECK-NEXT:                                        exact references
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-custom-descriptors         Disable custom descriptors (RTTs) and
;; CHECK-NEXT:                                        exact references
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-multibyte                   Enable multibyte array loads and stores
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-multibyte                  Disable multibyte array loads and stores
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-relaxed-atomics             Enable acquire/release atomic memory
;; CHECK-NEXT:                                        operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-relaxed-atomics            Disable acquire/release atomic memory
;; CHECK-NEXT:                                        operations
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-custom-page-sizes           Enable custom page sizes
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-custom-page-sizes          Disable custom page sizes
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-wide-arithmetic             Enable wide arithmetic
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-wide-arithmetic            Disable wide arithmetic
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-compact-imports             Enable compact import section
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-compact-imports            Disable compact import section
;; CHECK-NEXT:
;; CHECK-NEXT:   --enable-typed-function-references   Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT:   --disable-typed-function-references  Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT:   --no-validation,-n                   Disables validation, assumes inputs are
;; CHECK-NEXT:                                        correct
;; CHECK-NEXT:
;; CHECK-NEXT:   --pass-arg,-pa                       An argument passed along to optimization
;; CHECK-NEXT:                                        passes being run. Must be in the form
;; CHECK-NEXT:                                        KEY@VALUE.  If KEY is the name of a pass
;; CHECK-NEXT:                                        then it applies to the closest instance
;; CHECK-NEXT:                                        of that pass before us. If KEY is not the
;; CHECK-NEXT:                                        name of a pass then it is a global option
;; CHECK-NEXT:                                        that applies to all pass instances that
;; CHECK-NEXT:                                        read it.
;; CHECK-NEXT:
;; CHECK-NEXT:   --closed-world,-cw                   Assume code outside of the module does
;; CHECK-NEXT:                                        not inspect or interact with GC and
;; CHECK-NEXT:                                        function references, even if they are
;; CHECK-NEXT:                                        passed out. The outside may hold on to
;; CHECK-NEXT:                                        them and pass them back in, but not
;; CHECK-NEXT:                                        inspect their contents or call them.
;; CHECK-NEXT:
;; CHECK-NEXT:   --preserve-type-order                Preserve the order of types from the
;; CHECK-NEXT:                                        input (useful for debugging and testing)
;; CHECK-NEXT:
;; CHECK-NEXT:   --generate-stack-ir                  generate StackIR during writing
;; CHECK-NEXT:
;; CHECK-NEXT:   --optimize-stack-ir                  optimize StackIR during writing
;; CHECK-NEXT:
;; CHECK-NEXT:   --print-stack-ir                     print StackIR during writing
;; CHECK-NEXT:
;; CHECK-NEXT:
;; CHECK-NEXT: General options:
;; CHECK-NEXT: ----------------
;; CHECK-NEXT:
;; CHECK-NEXT:   --version                            Output version information and exit
;; CHECK-NEXT:
;; CHECK-NEXT:   --help,-h                            Show this help message and exit
;; CHECK-NEXT:
;; CHECK-NEXT:   --debug,-d                           Print debug information to stderr
;; CHECK-NEXT:
