cvise README

The project's README from github.com/marxin/cvise. As one markdown file: README.md.

C-Vise

Build Build LLVM nightly

About

C-Vise is a super-parallel Python port of the C-Reduce. The port is fully compatible to the C-Reduce and uses the same efficient LLVM-based C/C++ reduction tool named clang_delta.

This project is looking for maintainers — reach out to [@marxin] if you're interested.

C-Vise is a tool that takes a large C, C++ or OpenCL program that has a property of interest (such as triggering a compiler bug) and automatically produces a much smaller C/C++ or OpenCL program that has the same property. It is intended for use by people who discover and report bugs in compilers and other tools that process C/C++ or OpenCL code.

The project also contains a simple wrapper cvise-delta which simulates the same behavior as original delta tool (but in super-parallel way).

NOTE: C-Vise happens to do a pretty good job reducing the size of programs in languages other than C/C++, such as JavaScript and Rust. If you need to reduce programs in some other language, please give it a try.

NOTE: Binary pass group (--pass-group=binary) contains an experimental pass that can reduce GCC's .gcda files.

Speed Comparison

I made a comparison for couple of GCC bug reports on my AMD Ryzen 7 2700X Eight-Core Processor machine with the following results:

Test-case Size C-Vise Reduction C-Reduce Reduction Speed Up
PR92516 6.5 MB 35m 77m 220%
PR94523 2.1 MB 15m 33m 220%
PR94632 3.3 MB 20m 28m 40%
PR94937 8.5 MB 242m 303m 125%

Installation

See INSTALL.md.

Usage example

The C-Vise can be used for a reduction of a compiler crash. In this case, let's consider an existing PR94534:

Original test-case (pr94534.C file):

template<typename T>
class Demo
{
  struct
  {
    Demo* p;
  } payload{this};
  friend decltype(payload);
};

int main()
{
  Demo<int> d;
}

The program crashes in GCC, but is accepted with Clang:

$ g++ pr94534.C -c
pr94534.C: In instantiation of ‘class Demo<int>’:
pr94534.C:13:13:   required from here
pr94534.C:7:5: internal compiler error: Segmentation fault
    7 |   } payload{this};
      |     ^~~~~~~
0x10a1d8f crash_signal
	/home/marxin/Programming/gcc/gcc/toplev.c:328
0x7ffff78fef1f ???
	/usr/src/debug/glibc-2.31-4.1.x86_64/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
0xae31a8 instantiate_class_template_1
	/home/marxin/Programming/gcc/gcc/cp/pt.c:11973
...
$ clang++ pr94534.C -c

So let's build a reduction script so that it will grep for instantiate_class_template_1 on the standard error output and that it compiles with Clang:

reduce-ice.sh:

#!/bin/sh
g++ pr94534.C -c 2>&1 | grep 'instantiate_class_template_1' && clang++ -c pr94534.C

The reduction can be then run with:

$ cvise ./reduce-ice.sh pr94534.C
INFO ===< 30356 >===
INFO running 16 interestingness tests in parallel
INFO INITIAL PASSES
INFO ===< IncludesPass >===
...
template <typename> class a {
  int b;
  friend decltype(b);
};
void c() { a<int> d; }

Usage with multi-file inputs

C-Vise can also reduce test cases containing multiple files - they can be passed in the command line individually or as whole directories. The latter is generally more efficient and allows C-Vise perform following reductions:

For example, assuming the following directory tree:

//--- repro/h1.h
int x;

//--- repro/h2.h
#include "h1.h"

//--- repro/src1.c
#include "h2.h"

//--- repro/src2.c
// duplicate!
int x;

//--- repro/src3.c
int main() {
	return 0;
}

//--- repro/Makefile
.PHONY: all clean
all: prog
src1.o:
	gcc -c src1.c
src2.o:
	gcc -c src2.c
src3.o:
	gcc -c src3.c
prog: src1.o src2.o src3.o
	gcc -o prog src1.o src2.o src3.o
clean:
	rm -f src1.o src2.o src3.o prog

The reduction can be then run with:

$ cvise repro -c "(make -C repro 2>&1 || true) | grep 'multiple definition'"
...
Reduced test-cases:

--- repro ---

//--- repro/Makefile
.PHONY: all clean
all: prog
src1.o:
	gcc -c src1.c
src2.o:
	gcc -c src2.c
prog: src1.o src2.o
	gcc -o prog src1.o src2.o
clean:
	rm -f src1.o src2.o prog


//--- repro/src1.c
int x ;


//--- repro/src2.c
int x ;

Notes

  1. C-Vise creates temporary directories in $TMPDIR and so usage of a tmpfs directory is recommended.

  2. Each invocation of the interestingness test is performed in a fresh temporary directory containing a copy of the file that is being reduced. If your interestingness test requires access to other files, you should either copy them into the current working directory or else refer to them using an absolute path.

  3. If you copy the compiler invocation line from your build tool, remove -Werror if present. Some C-Vise passes introduce warnings, so -Werror will make those passes ineffective.

    Doing that, a reduction will typically end up faster, however, one may end up with a code snippet full of warnings that needs to be addresses after the reduction.

  4. Adding -Wfatal-errors to the interestingness test can speed up large reductions by causing the compiler to bail out quickly on errors, rather than trying to soldier on producing a result that is eventually discarded.

cvise (marxin/cvise)

Searching Database…

353 ·GitHub
What is this?C-Vise is a super-parallel Python port of C-Reduce. It shrinks a large C, C++ or OpenCL program while keeping one property, such as a compiler crash, so you get a much smaller test case.
Is it a standalone program or a library?A standalone command-line tool. You give it a file and an interestingness test script, and it writes out a smaller file that still passes the test.
Any gotchas to watch for?Yes. Remove -Werror from copied compile commands, since some passes add warnings. Each test runs in a fresh temp dir, so copy extra files in or use absolute paths.
Who should use it?Mainly people who find and report bugs in compilers and other tools that process C, C++ or OpenCL code.
Can it reduce GCC profile files?Yes, in a limited way. The binary pass group (--pass-group=binary) has an experimental pass that can reduce GCC's .gcda files.
Is there a drop-in replacement for delta?Yes. The cvise-delta wrapper mimics the behavior of the original delta tool, but runs in a super-parallel way.
What's the main difference from C-Reduce?It is a Python port that stays fully compatible with C-Reduce, but runs in parallel and uses the same LLVM-based clangdelta reducer.
Creator
marxin
Size
10.5 MB
Stars
353
Age
6y
Commits · 90 Days