Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc produces invalid IR with -O -g #28947

Closed
wthrowe opened this issue Oct 10, 2015 · 27 comments
Closed

rustc produces invalid IR with -O -g #28947

wthrowe opened this issue Oct 10, 2015 · 27 comments
Assignees
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@wthrowe
Copy link
Contributor

wthrowe commented Oct 10, 2015

When compiling rustc with "--enable-debug --enable-optimize" the stage0 compiler fails to build libsyntax with

!dbg attachment points at wrong subprogram for function
!157085 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !157069, file: !157069, line: 38, type: !42899, isLocal: true, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: true, function: i64 (%closure.1242*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69625E, templateParams: !1036, variables: !157086)
i64 (%closure.1242*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69625E
  tail call void @llvm.dbg.value(metadata %"ext::expand::IdentRenamer"* %rename_fld.i.857, i64 0, metadata !157464, metadata !190803), !dbg !771025
!771025 = !DILocation(line: 113, scope: !157458, inlinedAt: !771026)
!771027 = distinct !DILexicalBlock(scope: !771028, file: !157069, line: 129, column: 56)
!160753 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !157069, file: !157069, line: 129, type: !160754, isLocal: true, isDefinition: true, scopeLine: 129, flags: DIFlagPrototyped, isOptimized: true, templateParams: !1036, variables: !160756)
LLVM ERROR: Broken function found, compilation aborted!

This started with #28857, but it looks to me like that just happened to trigger a preexisting bug.

@jdm jdm added the A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) label Oct 10, 2015
@pnkfelix
Copy link
Member

I am able to reproduce this on my native linux system. I have not yet tried in a VM yet. Its a pretty bad show-stopper for Linux work (at least if one wants to use --enable-debug in a usable manner).

@dotdash
Copy link
Contributor

dotdash commented Oct 11, 2015

JFYI, I started looking into this.

@pnkfelix pnkfelix added the O-linux Operating system: Linux label Oct 12, 2015
@pnkfelix
Copy link
Member

(this problem does not reproduce on Mac OS X, which may be fortunate or unfortunate, depending on one's POV...)

Update: Now I have reproduced it on OS X. I am not sure where my earlier attempt to reproduce went wrong. Anyway, this heightens my desire to get this fixed considerably...

cc @nrc

@pnkfelix
Copy link
Member

@dotdash have you made much progress, e.g. have you made a reduced test case, or have insight into what's wrong?

I am wondering in part because I am willing to spend time looking at this, but I do not want to waste or duplicate effort.

@dotdash
Copy link
Contributor

dotdash commented Oct 13, 2015

Not much progress yet. For some reason, the inlinedAt chain for the
dbg.value calls is missing. AFAICT so far, our debug info looks fine (I
might be missing something though), so I'm looking at the LLVM code to see
how inlining handles debug info and how the conversion from dbg.declare
to dbg.value works.

2015-10-13 12:01 GMT+02:00 Felix S Klock II notifications@github.com:

@dotdash https://github.com/dotdash have you made much progress, e.g.
have you made a reduced test case, or have insight into what's wrong?

I am wondering in part because I am willing to spend time looking at this,
but I do not want to waste or duplicate effort.


Reply to this email directly or view it on GitHub
#28947 (comment).

@sanxiyn
Copy link
Member

sanxiyn commented Oct 13, 2015

Something weird is going on. -verify-each causes the error to disappear.

$ rustc -g --emit llvm-bc src/libsyntax/lib.rs
$ opt -O2 -disable-output syntax.bc
LLVM ERROR: Broken function found, compilation aborted!
$ opt -O2 -verify-each -disable-output syntax.bc

@ghost
Copy link

ghost commented Oct 14, 2015

Reproduced on a hardened gentoo linux (here's all you need to know about the system: http://dpaste.com/1DQ0EFB.txt ) as follows:

$ ./configure --prefix=/home/zazdxscf/build/1nonpkgs/rust/usr/local --disable-rpath --enable-manage-submodules --disable-clang --enable-ccache --enable-dist-host-only --disable-valgrind --disable-helgrind --disable-valgrind-rpass --python=/usr/bin/python2 --enable-optimize --enable-optimize-cxx --enable-optimize-llvm --enable-debug --enable-debuginfo --enable-debug-assertions --enable-debuginfo-tests --enable-llvm-assertions --enable-debug-jemalloc --disable-local-rust
...
$ time ( time make -j1 -- all NO_REBUILD=1 TIME_PASSES=1 TIME_LLVM_PASSES=1 RUSTFLAGS="--verbose" && time make check )
cfg: version 1.5.0-dev (294ef5b15 2015-10-14)
cfg: build triple x86_64-unknown-linux-gnu
cfg: host triples x86_64-unknown-linux-gnu
cfg: target triples x86_64-unknown-linux-gnu
cfg: enabling debug assertions (CFG_ENABLE_DEBUG_ASSERTIONS)
cfg: enabling debuginfo (CFG_ENABLE_DEBUGINFO)
cfg: host for x86_64-unknown-linux-gnu is x86_64
cfg: os for x86_64-unknown-linux-gnu is unknown-linux-gnu
cfg: good valgrind for x86_64-unknown-linux-gnu is 1
cfg: using CC=ccache gcc (CFG_CC)
cfg: disabling valgrind run-pass tests
rustc: x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/libsyntax
time: 0.381; rss: 58MB  parsing
time: 0.124; rss: 59MB  configuration 1
...
...
time: 25.515; rss: 929MB    translation
  time: 9.382; rss: 631MB   llvm function passes
  time: 202.128; rss: 738MB llvm module passes
!dbg attachment points at wrong subprogram for function
!156164 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !156148, file: !156148, line: 38, type: !42689, isLocal: true, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: true, function: i64 (%closure.1236*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69460E, templateParams: !1036, variables: !156165)
i64 (%closure.1236*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69460E
  tail call void @llvm.dbg.value(metadata %"ext::expand::IdentRenamer"* %rename_fld.i.857, i64 0, metadata !156543, metadata !189756), !dbg !766304
!766304 = !DILocation(line: 113, scope: !156537, inlinedAt: !766305)
!766306 = distinct !DILexicalBlock(scope: !766307, file: !156148, line: 129, column: 56)
!159806 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !156148, file: !156148, line: 129, type: !159807, isLocal: true, isDefinition: true, scopeLine: 129, flags: DIFlagPrototyped, isOptimized: true, templateParams: !1036, variables: !159809)
LLVM ERROR: Broken function found, compilation aborted!
/home/zazdxscf/build/1nonpkgs/rust/rust/mk/target.mk:164: recipe for target 'x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.syntax' failed
make: *** [x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.syntax] Error 1

rust commit tested: 294ef5b

In trying to follow sanxiyn's comment above, changing the above RUSTFLAGS to:
RUSTFLAGS="--verbose -C llvm-args=-verify-each"
fails after a while(I'm probably doing it wrong):

...
time: 0.820; rss: 327MB lint checking
time: 0.000; rss: 327MB resolving dependency formats
rustc: Unknown command line argument '-verify-each'.  Try: 'rustc -help'
rustc: Did you mean '-verify-scev'?
/home/zazdxscf/build/1nonpkgs/rust/rust/mk/target.mk:164: recipe for target 'x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.syntax' failed
make: *** [x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.syntax] Error 1

No idea where to stick that -verify-each at the moment, so that make would work with it. Any ideas?

EDIT1: It actually went past it with -verify-scev I'm guessing due to llvm version that rust compilation uses, instead of my installed version(3.7.0) which does have the -verify-each
But the original reported issue still happens (with -verify-scev): !dbg attachment points at wrong subprogram for function

EDIT2: I'm still getting the error that maybe I meant to use -verify-scev when trying with my own llvm and my own (local)rust, after a make clean and removal of directory rust/x86_64-unknown-linux-gnu/ then a configure then make

$ make clean
...
$ rm -rf x86_64-unknown-linux-gnu
...
$ ./configure --prefix=/home/zazdxscf/build/1nonpkgs/rust/usr/local --disable-rpath --enable-manage-submodules --disable-clang --enable-ccache --enable-dist-host-only --disable-valgrind --disable-helgrind --disable-valgrind-rpass --python=/usr/bin/python2 --enable-optimize --enable-optimize-cxx --enable-optimize-llvm --enable-debug --enable-debuginfo --enable-debug-assertions --enable-debuginfo-tests --enable-llvm-assertions --enable-debug-jemalloc --disable-local-rust --enable-local-rust --local-rust-root=/usr --llvm-root=/usr
...
$ make -j1 -- all NO_REBUILD=1 TIME_PASSES=1 TIME_LLVM_PASSES=1 'RUSTFLAGS=--verbose -C llvm-args=-verify-each'
...
time: 0.073; rss: 172MB stability checking
time: 0.000; rss: 172MB unused lib feature checking
src/libcore/lib.rs:82:12: 82:29 warning: unused or unknown feature, #[warn(unused_features)] on by default
src/libcore/lib.rs:82 #![feature(unwind_attributes)]
                                 ^~~~~~~~~~~~~~~~~
src/libcore/panicking.rs:65:9: 65:18 warning: unused attribute, #[warn(unused_attributes)] on by default
src/libcore/panicking.rs:65         #[unwind]
                                    ^~~~~~~~~
time: 1.496; rss: 172MB lint checking
time: 0.000; rss: 172MB resolving dependency formats
rustc: Unknown command line argument '-verify-each'.  Try: 'rustc -help'
rustc: Did you mean '-verify-scev'?
/home/zazdxscf/build/1nonpkgs/rust/rust/mk/target.mk:164: recipe for target 'x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.core' failed
make: *** [x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.core] Error 1

Does rustc maybe have a whitelisted llvm-args that's allowing to passthru ? Or how does it fail to use my llvm(3.7.0) which clearly does have that option ?
EDIT3: One more thing, I accidentally had --disable-local-rust with --enable-local-rust of which only the former took place but when I removed it:

time: 0.006; rss: 49MB  gated macro checking
time: 0.000; rss: 49MB  crate injection
src/libcore/lib.rs:1:1: 1:1 error: can't find crate for `std`
src/libcore/lib.rs:1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
                     ^
error: aborting due to previous error
/home/zazdxscf/build/1nonpkgs/rust/rust/mk/target.mk:164: recipe for target 'x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.core' failed
make: *** [x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.core] Error 101

but maybe I got the --local-rust-root="/usr" wrong, I've no idea which is right since it fails the same with /usr/local . I'll stick with supplied rustc then.

EDIT4: ok, the reason -verify-each fails is because it's passed to llc instead of to opt (commands) and for some reason llc doesn't have it but opt does.

EDIT5: tested with git llvm (3.8.0) and the error still happens:

$ make -j1 -- all NO_REBUILD=1 TIME_PASSES=1 TIME_LLVM_PASSES=1 'RUSTFLAGS=--verbose -Z verbose -Z print-link-args -Z debug-llvm -Z          unstable-options -C llvm-args="-verify-debug-info -verify-dom-info -verify-loop-info -verify-regalloc -verify-region-info -verify-scev"'
...
rustc: x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/libsyntax
...
time: 25.511; rss: 928MB    translation
  time: 9.280; rss: 631MB   llvm function passes
  time: 200.468; rss: 740MB llvm module passes
!dbg attachment points at wrong subprogram for function
!156127 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !156111, file: !156111, line: 38, type: !42675, isLocal: true, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: true, function: i64 (%closure.1236*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69395E, templateParams: !1032, variables: !156128)
i64 (%closure.1236*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69395E
  tail call void @llvm.dbg.value(metadata %"ext::expand::IdentRenamer"* %rename_fld.i.857, i64 0, metadata !156506, metadata !189686), !dbg !765837
!765837 = !DILocation(line: 113, scope: !156500, inlinedAt: !765838)
!765839 = distinct !DILexicalBlock(scope: !765840, file: !156111, line: 129, column: 56)
!159769 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !156111, file: !156111, line: 129, type: !159770, isLocal: true, isDefinition: true, scopeLine: 129, flags: DIFlagPrototyped, isOptimized: true, templateParams: !1032, variables: !159772)
LLVM ERROR: Broken function found, compilation aborted!
/home/zazdxscf/build/1nonpkgs/rust/rust/mk/target.mk:164: recipe for target 'x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.syntax' failed
make: *** [x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.syntax] Error 1

real    16m51.405s
user    15m38.200s
sys 0m49.577s

latest rust commit tested 1ad1b7d
Maybe I'll get back to rust some other time.

@pnkfelix pnkfelix added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 15, 2015
@dotdash dotdash self-assigned this Oct 15, 2015
@nikomatsakis
Copy link
Contributor

triage: P-medium

@rust-highfive rust-highfive added P-medium Medium priority and removed I-nominated labels Oct 15, 2015
@pnkfelix
Copy link
Member

I would really like to see a narrowed test case for this bug. I've tried to start working my way down from libsyntax but keep getting interrupted (or flummoxed -- my usual tools for this like --unpretty everybody_loops did not yield immediate results...)

@dotdash
Copy link
Contributor

dotdash commented Oct 15, 2015

I tried stripping most "unrelated" functions from the generated IR for libsyntax, but even that made the bug disappear at some point.

@pnkfelix
Copy link
Member

(at some point we may have to ask ourselves if we are willing to revert the lowering PR, if only to allow us to finally set up gating bors via the buildbot with --enable-optimize --enable-debug ...)

@ghost
Copy link

ghost commented Oct 16, 2015

tldr; I don't know how helpful this is but, using --disable-debuginfo does not cause the issue.

In other words, this causes the issue --disable-debug --enable-debuginfo --enable-optimize --llvm-root=/usr (tested)

Last tested commit beeaea4, with --disable-debuginfo which doesn't cause the issue and then by changing it to enable, as follows:

$ ./configure --prefix=/home/zazdxscf/build/1nonpkgs/rust/usr/local --disable-rpath --enable-manage-submodules --disable-clang --enable-ccache --enable-dist-host-only --disable-valgrind --disable-helgrind --disable-valgrind-rpass --python=/usr/bin/python2 --enable-optimize --enable-optimize-cxx --enable-optimize-llvm --enable-debug --disable-debuginfo --enable-debug-assertions --enable-debuginfo-tests --enable-llvm-assertions --enable-debug-jemalloc --disable-llvm-version-check --disable-local-rust --llvm-root=/usr
...
$ make -j1 -- all NO_REBUILD=1 TIME_PASSES=1 TIME_LLVM_PASSES=1 'RUSTFLAGS=--verbose -Z verbose -Z print-link-args -Z debug-llvm '
...
time: 20.675; rss: 703MB    translation
  time: 7.623; rss: 402MB   llvm function passes
  time: 154.266; rss: 482MB llvm module passes
  time: 61.107; rss: 516MB  codegen passes
  time: 0.007; rss: 482MB   codegen passes
//so it passed with --disable-debuginfo
//next: changed --disable-debuginfo into --enable-debuginfo to make it fail
...
$ make clean
...
$ ./configure --prefix=/home/zazdxscf/build/1nonpkgs/rust/usr/local --disable-rpath --enable-manage-submodules --disable-clang --enable-ccache --enable-dist-host-only --disable-valgrind --disable-helgrind --disable-valgrind-rpass --python=/usr/bin/python2 --enable-optimize --enable-optimize-cxx --enable-optimize-llvm --enable-debug --enable-debuginfo --enable-debug-assertions --enable-debuginfo-tests --enable-llvm-assertions --enable-debug-jemalloc --disable-llvm-version-check --disable-local-rust --llvm-root=/usr
...
$ time make -j1 -- all NO_REBUILD=1 TIME_PASSES=1 TIME_LLVM_PASSES=1 'RUSTFLAGS=--verbose -Z verbose -Z print-link-args -Z debug-llvm '
...
rustc: x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/libsyntax
time: 0.391; rss: 58MB  parsing
time: 0.127; rss: 59MB  configuration 1
time: 0.000; rss: 59MB  recursion limit
time: 0.009; rss: 59MB  gated macro checking
time: 0.000; rss: 59MB  crate injection
time: 0.019; rss: 61MB  macro loading
time: 0.000; rss: 61MB  plugin loading
time: 0.000; rss: 61MB  plugin registration
time: 1.831; rss: 94MB  expansion
time: 0.036; rss: 94MB  complete gated feature checking 1
time: 0.322; rss: 94MB  configuration 2
time: 0.166; rss: 94MB  maybe building test harness
time: 0.154; rss: 94MB  prelude injection
time: 0.021; rss: 94MB  checking that all macro invocations are gone
time: 0.037; rss: 94MB  complete gated feature checking 2
time: 0.196; rss: 103MB assigning node ids and indexing ast
time: 0.024; rss: 103MB external crate/lib resolution
time: 0.044; rss: 103MB language item collection
time: 0.696; rss: 148MB resolution
time: 0.033; rss: 143MB lifetime resolution
time: 0.000; rss: 143MB looking for entry point
time: 0.021; rss: 143MB looking for plugin registrar
time: 0.263; rss: 158MB region resolution
time: 0.022; rss: 158MB loop checking
time: 0.024; rss: 158MB static item recursion checking
time: 0.151; rss: 161MB type collecting
time: 0.044; rss: 161MB variance inference
time: 0.455; rss: 202MB coherence checking
time: 23.707; rss: 308MB    type checking
time: 4.946; rss: 319MB const checking
time: 0.198; rss: 320MB privacy checking
time: 0.005; rss: 320MB stability index
time: 0.067; rss: 320MB intrinsic checking
time: 0.051; rss: 320MB effect checking
time: 1.123; rss: 320MB match checking
time: 0.176; rss: 327MB liveness checking
time: 9.925; rss: 327MB borrow checking
time: 5.309; rss: 327MB rvalue checking
time: 0.064; rss: 327MB reachability checking
time: 0.152; rss: 327MB death checking
time: 0.178; rss: 327MB stability checking
time: 0.000; rss: 327MB unused lib feature checking
time: 0.801; rss: 327MB lint checking
time: 0.000; rss: 327MB resolving dependency formats
time: 25.456; rss: 928MB    translation
  time: 9.374; rss: 631MB   llvm function passes
  time: 201.226; rss: 740MB llvm module passes
!dbg attachment points at wrong subprogram for function
!156127 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !156111, file: !156111, line: 38, type: !42675, isLocal: true, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: true, function: i64 (%closure.1236*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69395E, templateParams: !1032, variables: !156128)
i64 (%closure.1236*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69395E
  tail call void @llvm.dbg.value(metadata %"ext::expand::IdentRenamer"* %rename_fld.i.857, i64 0, metadata !156506, metadata !189686), !dbg !765837
!765837 = !DILocation(line: 113, scope: !156500, inlinedAt: !765838)
!765839 = distinct !DILexicalBlock(scope: !765840, file: !156111, line: 129, column: 56)
!159769 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !156111, file: !156111, line: 129, type: !159770, isLocal: true, isDefinition: true, scopeLine: 129, flags: DIFlagPrototyped, isOptimized: true, templateParams: !1032, variables: !159772)
LLVM ERROR: Broken function found, compilation aborted!
/home/zazdxscf/build/1nonpkgs/rust/rust/mk/target.mk:164: recipe for target 'x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.syntax' failed
make: *** [x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.syntax] Error 1

real    9m11.276s
user    8m21.940s
sys 0m40.597s

So, replacing --disable-debuginfo with --enable-debuginfo in the above, causes the issue. Btw, --enable-debug implies --enable-debuginfo unless --disable-debuginfo is specified.

If it matters,
$ llc --version
LLVM (http://llvm.org/):
LLVM version 3.8.0svn
Optimized build.
Default target: x86_64-pc-linux-gnu
Host CPU: (unknown)

Registered Targets:
amdgcn - AMD GCN GPUs
cpp - C++ backend
r600 - AMD GPUs HD2XXX-HD6XXX
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64

Now that I think about it, it's actually in the issue's title -g is the --enable-debuginfo ... also in sanxiyn's comment, which makes me want to test this:

$ time x86_64-unknown-linux-gnu/stage0/bin/rustc -g --emit llvm-bc src/libsyntax/lib.rs
real    1m23.926s
user    1m20.543s
sys 0m3.040s

$ time opt -O2 -disable-output syntax.bc
real    4m24.718s
user    4m23.393s
sys 0m0.653s
//oh wait, what? this worked this time?! WHAT? :) without -verify-each and with --enable-debuginfo that was left from above.
//I don't get it; is it my 3.8.0 llc ? I don't remember if I used this llc version to test this
...

Going to try using llvm that comes with rust next.

Btw, compiling the llvm that comes with rust (when I don't specify --llvm-root=/usr to configure) doesn't use ccache even though I've --enable-ccache set.

EDIT1: Actually I was wrong, it DOES USE CCACHE! (I was just looking in the wrong ccache folder! with ccache -s)

@dotdash
Copy link
Contributor

dotdash commented Oct 16, 2015

Note that rustc generates different IR even pre-optimization when using -O. For example, lifetime intrinsics aren't used (and thus don't show up in the IR/bitcode) if -O isn't used.

@dotdash
Copy link
Contributor

dotdash commented Oct 16, 2015

@sanxiyn -verify-each only inserts the verifier after each pass given on the command line, not after those inserted by -O2. It also removes the final verifier run. IOW with opt -verify-each -O2, the verifier doesn't run at all.

@ghost
Copy link

ghost commented Oct 16, 2015

tl;dr it now fails with -verify-each too; and works without -g (as implied in the issue's title)

Very nice, thanks dotdash for the help. While I basically have no idea what I'm doing, I can now reproduce (again) sanxiyn's comment by adding -O to rustc which adds 20meg to the output syntax.bc file (it's 45 meg now).

$ time LD_LIBRARY_PATH='/home/zazdxscf/build/1nonpkgs/rust/rust/x86_64-unknown-linux-gnu/stage0/lib' x86_64-unknown-linux-gnu/stage0/bin/rustc -O -g --emit llvm-bc src/libsyntax/lib.rs

real    4m45.443s
user    4m41.333s
sys 0m3.127s

$ time opt -O2 -disable-output syntax.bc
!dbg attachment points at wrong subprogram for function
!154953 = distinct !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !154937, file: !154937, line: 38, type: !42660, isLocal: true, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: true, function: i64 (%closure.1235*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.68893E, templateParams: !1032, variables: !154954)
i64 (%closure.1235*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.68893E
  tail call void @llvm.dbg.value(metadata %"ext::expand::IdentRenamer"* %rename_fld.i.763, i64 0, metadata !155332, metadata !188522), !dbg !882290
!882290 = !DILocation(line: 113, scope: !155326, inlinedAt: !882291)
!882292 = distinct !DILexicalBlock(scope: !882293, file: !154937, line: 129, column: 56)
!158595 = distinct !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !154937, file: !154937, line: 129, type: !158596, isLocal: true, isDefinition: true, scopeLine: 129, flags: DIFlagPrototyped, isOptimized: true, templateParams: !1032, variables: !158598)
opt: syntax.bc: error: input module is broken!

real    0m12.978s
user    0m12.263s
sys 0m0.657s

$ time opt -O2 -verify-each -disable-output syntax.bc
!dbg attachment points at wrong subprogram for function
!154953 = distinct !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !154937, file: !154937, line: 38, type: !42660, isLocal: true, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: true, function: i64 (%closure.1235*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.68893E, templateParams: !1032, variables: !154954)
i64 (%closure.1235*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.68893E
  tail call void @llvm.dbg.value(metadata %"ext::expand::IdentRenamer"* %rename_fld.i.763, i64 0, metadata !155332, metadata !188522), !dbg !882290
!882290 = !DILocation(line: 113, scope: !155326, inlinedAt: !882291)
!882292 = distinct !DILexicalBlock(scope: !882293, file: !154937, line: 129, column: 56)
!158595 = distinct !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !154937, file: !154937, line: 129, type: !158596, isLocal: true, isDefinition: true, scopeLine: 129, flags: DIFlagPrototyped, isOptimized: true, templateParams: !1032, variables: !158598)
opt: syntax.bc: error: input module is broken!

real    0m12.416s
user    0m11.690s
sys 0m0.673s
//yup, fails with -verify-each too  (also tested by adding all other -verify* options, still no change)

//even with the llvm that comes with rust, still fails with -verify-each unless I'm doing it wrong and it uses stuff from the svn llvm that I've installed
$ time LD_LIBRARY_PATH='/home/zazdxscf/build/1nonpkgs/rust/rust/x86_64-unknown-linux-gnu/llvm/Release+Asserts/lib' x86_64-unknown-linux-gnu/llvm/Release+Asserts/bin/opt -O2 -verify-each -disable-output syntax.bc 
!dbg attachment points at wrong subprogram for function
!154953 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !154937, file: !154937, line: 38, type: !42660, isLocal: true, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: true, function: i64 (%closure.1235*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.68893E, templateParams: !1032, variables: !154954)
i64 (%closure.1235*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.68893E
  tail call void @llvm.dbg.value(metadata %"ext::expand::IdentRenamer"* %rename_fld.i.763, i64 0, metadata !155332, metadata !188522), !dbg !882290
!882290 = !DILocation(line: 113, scope: !155326, inlinedAt: !882291)
!882292 = distinct !DILexicalBlock(scope: !882293, file: !154937, line: 129, column: 56)
!158595 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !154937, file: !154937, line: 129, type: !158596, isLocal: true, isDefinition: true, scopeLine: 129, flags: DIFlagPrototyped, isOptimized: true, templateParams: !1032, variables: !158598)
x86_64-unknown-linux-gnu/llvm/Release+Asserts/bin/opt: syntax.bc: error: input module is broken!

real    0m14.177s
user    0m13.450s
sys 0m0.630s

$ opt --version
LLVM (http://llvm.org/):
  LLVM version 3.8.0svn
  Optimized build.
  Default target: x86_64-pc-linux-gnu
  Host CPU: (unknown)

//so what I wanted to try before was  not using -g  to see if the issue disappears and it does:
$ time LD_LIBRARY_PATH='/home/zazdxscf/build/1nonpkgs/rust/rust/x86_64-unknown-linux-gnu/stage0/lib' x86_64-unknown-linux-gnu/stage0/bin/rustc -O --emit llvm-bc src/libsyntax/lib.rs

real    3m40.865s
user    3m37.717s
sys 0m2.530s

$ time opt -O2 -disable-output syntax.bc
real    1m29.530s
user    1m28.343s
sys 0m0.910s

EDIT: dotdash's previous comment explains why -verify-each doesn't work anymore.

@dotdash
Copy link
Contributor

dotdash commented Oct 16, 2015

It fails with -verify-each in that case, because the output you got from rustc was already optimized, i.e. broken, and the verifier runs early (during function passes, IIRC). To get the unoptimized IR even from a build with -O, use -Csave-temps. That gives you a syntax.0.no-opt.bc file which has no optimizations applied at all.

@nikomatsakis
Copy link
Contributor

Felix raised the quesiton with me on IRC if we consider this
P-high. I'm not sure, but we may have misclassified -- -O -g is
pretty important! (Not that it makes that big a difference in practice
I guess.) I guess what I don't know is how many programs are affected
by this problem (and I guess cargo makes -O -g hard to do?)

On Thu, Oct 15, 2015 at 02:04:03PM -0700, Felix S Klock II wrote:

(at some point we may have to ask ourselves if we are willing to revert the lowering PR, if only to allow us to finally set up gating bors via the buildbot with --enable-optimize --enable-debug ...)


Reply to this email directly or view it on GitHub:
#28947 (comment)

@ghost
Copy link

ghost commented Oct 16, 2015

But doesn't that mean that in the case of NOT passing -O, with -Csave-temps I should be getting the same file contents for syntax.0.no-opt.bc and syntax.bc ? Or is there some kind of optimization going on nonetheless? There's about 900KB difference.

$ time x86_64-unknown-linux-gnu/stage0/bin/rustc -g --emit llvm-bc -Csave-temps src/libsyntax/lib.rs

real    1m27.220s
user    1m22.487s
sys 0m4.070s

$ la *.bc
-rw-r--r-- 1 zazdxscf zazdxscf 25854804 16.10.2015 16:20 syntax.0.bc
-rw-r--r-- 1 zazdxscf zazdxscf 24978784 16.10.2015 16:20 syntax.0.no-opt.bc
-rw-r--r-- 1 zazdxscf zazdxscf 25854804 16.10.2015 16:20 syntax.bc
-rw-r--r-- 1 zazdxscf zazdxscf  3356724 16.10.2015 16:20 syntax.metadata.bc

$ time opt -O2 -disable-output syntax.0.no-opt.bc

real    4m21.647s
user    4m20.130s
sys 0m0.747s

$ time opt -O2 -disable-output syntax.bc

real    4m22.069s
user    4m20.267s
sys 0m1.027s

Here's with -O

$ time x86_64-unknown-linux-gnu/stage0/bin/rustc -O -g --emit llvm-bc -Csave-temps src/libsyntax/lib.rs

real    4m49.277s
user    4m43.473s
sys 0m4.227s

$ ls -la *.bc
-rw-r--r-- 1 zazdxscf zazdxscf 45058444 Oct 16 16:33 syntax.0.bc
-rw-r--r-- 1 zazdxscf zazdxscf 30834276 Oct 16 16:30 syntax.0.no-opt.bc
-rw-r--r-- 1 zazdxscf zazdxscf 45058444 Oct 16 16:33 syntax.bc
-rw-r--r-- 1 zazdxscf zazdxscf  3356804 Oct 16 16:33 syntax.metadata.bc

$ time opt -O2 -disable-output syntax.bc
!dbg attachment points at wrong subprogram for function
!154953 = distinct !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !154937, file: !154937, line: 38, type: !42660, isLocal: true, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: true, function: i64 (%closure.1235*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.68893E, templateParams: !1032, variables: !154954)
i64 (%closure.1235*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.68893E
  tail call void @llvm.dbg.value(metadata %"ext::expand::IdentRenamer"* %rename_fld.i.763, i64 0, metadata !155332, metadata !188522), !dbg !882290
!882290 = !DILocation(line: 113, scope: !155326, inlinedAt: !882291)
!882292 = distinct !DILexicalBlock(scope: !882293, file: !154937, line: 129, column: 56)
!158595 = distinct !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !154937, file: !154937, line: 129, type: !158596, isLocal: true, isDefinition: true, scopeLine: 129, flags: DIFlagPrototyped, isOptimized: true, templateParams: !1032, variables: !158598)
opt: syntax.bc: error: input module is broken!

real    0m13.200s
user    0m12.507s
sys 0m0.627s
//the above also fails with -verify-each also, for obvious reasons as mentioned above by dotdash

$ time opt -O2 -disable-output syntax.0.no-opt.bc

real    5m15.866s
user    5m13.743s
sys 0m0.807s
//yup works without -verify-each

What's curious though, is that previously I was able to reproduce this: #28947 (comment)
but now not anymore(as seen above) and I've no idea why
IOW, without passing -O to rustc, the issue would occur unless -verify-each.
But now it only occurs when rustc does it's optimize(-O) with output in syntax.bc file, but not when opt does its on syntax.0.no-opt.bc (as seen above) [-verify-each not needed]

Is there a way to see what command(s) rustc invokes to generate that syntax.bc from that syntax.0.no-opt.bc when -O is specified? Maybe we can see what args it passes to opt so that we can apply the same args when invoking opt manually... I don't know.

EDIT: also note the almost 5 meg difference between the two syntax.0.no-opt.bc for when using and not using -O , or maybe I misunderstood dotdash's comment? To get the unoptimized IR even from a build with -O, use -Csave-temps. That gives you a syntax.0.no-opt.bc file which has no optimizations applied at all.
EDIT2: What if, the issue would go away if only we had an up to date rustc (currently: $ x86_64-unknown-linux-gnu/stage0/bin/rustc --version
rustc 1.4.0-dev (1af31d4 2015-08-11)
) maybe due to some llvm fix(in case llvm stuff is embded in rustc; or a llvm update in case rustc needs llvm to compile stuff) or else I can't explain what I'm seeing here and why I cannot reproduce this anymore #28947 (comment)
But then again, I don't know much so... :)

@ghost
Copy link

ghost commented Oct 16, 2015

I can now confirm that #28947 (comment) can only be reproduced with opt from version 3.7.0 but not from 3.8.0 (svn/git)

//3.8.0 svn
$ time opt -O2 -disable-output syntax.bc
real    4m22.447s
user    4m20.920s
sys 0m0.633s

//3.7.0
$ time opt -O2 -disable-output syntax.bc
!dbg attachment points at wrong subprogram for function
!65002 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !64994, file: !64994, line: 38, type: !29584, isLocal: true, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: false, function: i64 (%closure.1236*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69391E, templateParams: !1032, variables: !1032)
i64 (%closure.1236*, %"ast::Expr"*)* @_ZN3ext6expand11expand_expr13closure.69391E
  tail call void @llvm.dbg.value(metadata %"ext::expand::IdentRenamer"* %rename_fld.i.686, i64 0, metadata !715374, metadata !76148), !dbg !717137
!717137 = !DILocation(line: 113, scope: !65097, inlinedAt: !717138)
!717139 = distinct !DILexicalBlock(scope: !717140, file: !64994, line: 129, column: 56)
!65968 = !DISubprogram(name: "fnfn", linkageName: "fnfn", scope: !64994, file: !64994, line: 129, type: !65969, isLocal: true, isDefinition: true, scopeLine: 129, flags: DIFlagPrototyped, isOptimized: false, templateParams: !1032, variables: !1032)
LLVM ERROR: Broken function found, compilation aborted!

real    3m43.535s
user    3m42.020s
sys 0m0.753s

Therefore, if rustc has llvm code embeded in it(I don't know this) then a recompile(with llvm 3.8.0 that is) should fix this, right? the stage 0 rustc that gets downloaded I mean (which currently was this: rustc 1.4.0-dev (1af31d4 2015-08-11) )

So, the issue should be gone with a rustc that uses is compiled with llvm 3.8.0 or whicever commit in llvm fixed this.

EDIT: the 3.8.0 llvm was at commit: f657b6395ac5c9fa57a3d4c871d7f32c565b11fe
the 3.7.0 was, I don't know it's the one that comes with gentoo:
$ opt --version
LLVM (http://llvm.org/):
LLVM version 3.7.0
Optimized build.
Default target: x86_64-pc-linux-gnu
Host CPU: (unknown)

@nagisa
Copy link
Member

nagisa commented Oct 16, 2015

I too am affected.

EDIT:

at some point we may have to ask ourselves if we are willing to revert the lowering PR

This is not an option, really, because it would delay landing <- indefinitely.

@ghost
Copy link

ghost commented Oct 16, 2015

In my attempt to compile myself a rustc for stage0 to use it to recompile rust with --enable-debuginfo I'm failing because of this llvm commit llvm-mirror/llvm@6f565c0
EDIT2: also this commit: llvm-mirror/llvm@aa50fa7

More exactly, when compiling rust with --disable-debuginfo, the error is :

$ ./configure --prefix=/home/zazdxscf/build/1nonpkgs/rust/usr/local --disable-rpath --enable-manage-submodules --disable-clang --enable-ccache --enable-dist-host-only --disable-valgrind --disable-helgrind --disable-valgrind-rpass --python=/usr/bin/python2 --enable-optimize --enable-optimize-cxx --enable-optimize-llvm --enable-debug --disable-debuginfo --enable-debug-assertions --enable-debuginfo-tests --enable-llvm-assertions --enable-debug-jemalloc --disable-local-rust --disable-llvm-version-check --llvm-root=/usr
...
//this is a rerun after the error happened already:
$ make -j1 -- all NO_REBUILD=1 TIME_PASSES=1 TIME_LLVM_PASSES=1 'RUSTFLAGS=--verbose -Z verbose -Z print-link-args'
cfg: version 1.5.0-dev (24228fee1 2015-10-16)
cfg: build triple x86_64-unknown-linux-gnu
cfg: host triples x86_64-unknown-linux-gnu
cfg: target triples x86_64-unknown-linux-gnu
cfg: enabling debug assertions (CFG_ENABLE_DEBUG_ASSERTIONS)
cfg: host for x86_64-unknown-linux-gnu is x86_64
cfg: os for x86_64-unknown-linux-gnu is unknown-linux-gnu
cfg: good valgrind for x86_64-unknown-linux-gnu is 1
cfg: using CC=ccache gcc (CFG_CC)
cfg: disabling valgrind run-pass tests
compile: x86_64-unknown-linux-gnu/rustllvm/RustWrapper.o
/home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp: In function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateSubroutineType(DIBuilderRef, LLVMMetadataRef, LLVMMetadataRef)':
/home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp:325:56: error: no matching function for call to 'llvm::DIBuilder::createSubroutineType(llvm::DIFile*, llvm::DITypeRefArray)'
         DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
                                                        ^
In file included from /home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/rustllvm.h:56:0,
                 from /home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp:11:
/usr/include/llvm/IR/DIBuilder.h:382:23: note: candidate: llvm::DISubroutineType* llvm::DIBuilder::createSubroutineType(llvm::DITypeRefArray, unsigned int)
     DISubroutineType *createSubroutineType(DITypeRefArray ParameterTypes,
                       ^
/usr/include/llvm/IR/DIBuilder.h:382:23: note:   no known conversion for argument 1 from 'llvm::DIFile*' to 'llvm::DITypeRefArray'
/home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp: In function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateVariable(DIBuilderRef, unsigned int, LLVMMetadataRef, const char*, LLVMMetadataRef, unsigned int, LLVMMetadataRef, bool, unsigned int, int64_t*, unsigned int, unsigned int)':
/home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp:505:26: error: 'class llvm::DIBuilder' has no member named 'createLocalVariable'
     return wrap(Builder->createLocalVariable(Tag,
                          ^
/home/zazdxscf/build/1nonpkgs/rust/rust/mk/rustllvm.mk:60: recipe for target 'x86_64-unknown-linux-gnu/rustllvm/RustWrapper.o' failed
make: *** [x86_64-unknown-linux-gnu/rustllvm/RustWrapper.o] Error 1

real    0m8.069s
user    0m6.697s
sys 0m1.237s

Should I maybe try to find out which commit(s) on top of 3.7.0 actually fixes the originally reported issue? instead of trying to make rust compile for 3.8.0 (which I know has the issue fixed) [the issue I'm referring to, in case I'm not being clear, is LLVM ERROR: Broken function found, compilation aborted! as reported in first comment]

Hmm, apparently this: llvm-mirror/llvm@9b38085
EDIT1: probably not that, I only searched for the msg, there's also this llvm-mirror/llvm@5db3146
But this one's mentioning something related at least: llvm-mirror/llvm@b683b29

@sanxiyn
Copy link
Member

sanxiyn commented Oct 17, 2015

Re @nikomatsakis "how many programs are affected by this problem", can we use Crater run to find out? (If so, I also hope this may provide a smaller test case.)

@sanxiyn
Copy link
Member

sanxiyn commented Oct 17, 2015

Bisecting LLVM against opt -O2 -disable-output syntax.bc led to LLVM r245588. Backporting the patch to Rust's fork of LLVM seems to fix the issue.

I said "seems", because fixing --enable-debug --enable-optimize build itself requires snapshot. On the other hand, normal rustc built against fixed LLVM does successfully compile libsyntax with -O -g.

We also should nominate the patch for LLVM 3.7.1.

@ghost
Copy link

ghost commented Oct 17, 2015

Thanks so much sanxiyn for finding that commit! It would've taken me days to learn how to find it, not having the experience and know how.

The same commit in git is here: llvm-mirror/llvm@0f8344c
appending .patch to the url gives the wget-able patch.

LLVM people did say they cherry-picked commits for 3.7.0, so maybe they already did pick (or will easily do so) this commit for 3.7.1

@sanxiyn
Copy link
Member

sanxiyn commented Oct 17, 2015

The patch is not included in LLVM 3.7.0 release and is not included in release_37 branch, so it is not the case they already picked it.

@ghost
Copy link

ghost commented Oct 17, 2015

For 3.7.1 I meant, but you're right it's not already picked (although some others are) https://github.com/llvm-mirror/llvm/commits/release_37

EDIT: I've tried to locally backport that patch to the llvm submodule(the llvm that comes with rust) but don't really know how (keeps getting reset to HEAD, and when it doesn't it fails by not finding some 'utility' include file) so I recompiled my system llvm 3.7.0 with the patch, but something's still failing when compiling rust:

...
compile: x86_64-unknown-linux-gnu/rustllvm/RustWrapper.o
/home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp: In function 'LLVMOpaqueValue* LLVMRustBuildLandingPad(LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, unsigned int, const char*, LLVMValueRef)':
/home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp:954:69: error: invalid conversion from 'LLVMValueRef {aka LLVMOpaqueValue*}' to 'unsigned int' [-fpermissive]
     return LLVMBuildLandingPad(Builder, Ty, PersFn, NumClauses, Name);
                                                                     ^
/home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp:954:69: error: invalid conversion from 'unsigned int' to 'const char*' [-fpermissive]
/home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp:954:69: error: too many arguments to function 'LLVMOpaqueValue* LLVMBuildLandingPad(LLVMBuilderRef, LLVMTypeRef, unsigned int, const char*)'
In file included from /usr/include/llvm/IR/Value.h:17:0,
                 from /usr/include/llvm/IR/User.h:24,
                 from /usr/include/llvm/IR/Instruction.h:22,
                 from /usr/include/llvm/IR/BasicBlock.h:19,
                 from /usr/include/llvm/IR/IRBuilder.h:21,
                 from /home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/rustllvm.h:11,
                 from /home/zazdxscf/build/1nonpkgs/rust/rust/src/rustllvm/RustWrapper.cpp:11:
/usr/include/llvm-c/Core.h:2677:14: note: declared here
 LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
              ^
/home/zazdxscf/build/1nonpkgs/rust/rust/mk/rustllvm.mk:60: recipe for target 'x86_64-unknown-linux-gnu/rustllvm/RustWrapper.o' failed
make: *** [x86_64-unknown-linux-gnu/rustllvm/RustWrapper.o] Error 1

I guess I'll wait until rust's llvm gets that patch.

@dotdash
Copy link
Contributor

dotdash commented Oct 17, 2015

Thanks for identifying the commit that fixed this issue upstream. I'm going to cherry-pick that commit to our LLVM fork and create a PR to update to that and disable -g in stage0 until we have a new snapshot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants