Merge pull request #224 from rust-lang/fix/gep-release-mode

Add CI tests with a sysroot compiled in release mode
This commit is contained in:
antoyo 2022-10-01 12:59:27 -04:00 committed by GitHub
commit 98f0dc148d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 146 additions and 21 deletions

112
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,112 @@
name: CI with sysroot compiled in release mode
on:
- push
- pull_request
permissions:
contents: read
env:
# Enable backtraces for easier debugging
RUST_BACKTRACE: 1
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
libgccjit_version:
- { gcc: "libgccjit.so", artifacts_branch: "master" }
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v2
with:
repository: llvm/llvm-project
path: llvm
- name: Install packages
run: sudo apt-get install ninja-build ripgrep
- name: Download artifact
uses: dawidd6/action-download-artifact@v2
with:
workflow: main.yml
name: ${{ matrix.libgccjit_version.gcc }}
path: gcc-build
repo: antoyo/gcc
branch: ${{ matrix.libgccjit_version.artifacts_branch }}
event: push
search_artifacts: true # Because, instead, the action only check the last job ran and that won't work since we want multiple artifacts.
- name: Setup path to libgccjit
run: |
echo $(readlink -f gcc-build) > gcc_path
# NOTE: the filename is still libgccjit.so even when the artifact name is different.
ln gcc-build/libgccjit.so gcc-build/libgccjit.so.0
- name: Set env
run: |
echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV
echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV
echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV
- name: Set RUST_COMPILER_RT_ROOT
run: echo "RUST_COMPILER_RT_ROOT="${{ env.workspace }}/llvm/compiler-rt >> $GITHUB_ENV
# https://github.com/actions/cache/issues/133
- name: Fixup owner of ~/.cargo/
# Don't remove the trailing /. It is necessary to follow the symlink.
run: sudo chown -R $(whoami):$(id -ng) ~/.cargo/
- name: Cache cargo installed crates
uses: actions/cache@v1.1.2
with:
path: ~/.cargo/bin
key: cargo-installed-crates2-ubuntu-latest
- name: Cache cargo registry
uses: actions/cache@v1
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v1
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
uses: actions/cache@v1.1.2
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }}
- name: Build
run: |
./prepare_build.sh
./build.sh --release --release-sysroot
cargo test
./clean_all.sh
- name: Prepare dependencies
run: |
git config --global user.email "user@example.com"
git config --global user.name "User"
./prepare.sh
# Compile is a separate step, as the actions-rs/cargo action supports error annotations
- name: Compile
uses: actions-rs/cargo@v1.0.3
with:
command: build
args: --release
- name: Run tests
run: |
./test.sh --release --clean --release-sysroot --build-sysroot --mini-tests --std-tests # --test-libcore # FIXME(antoyo): libcore tests fail.

View File

@ -57,6 +57,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<GccCodegenBackend>, _diag_han
if env::var("CG_GCCJIT_DUMP_TO_FILE").as_deref() == Ok("1") {
let _ = fs::create_dir("/tmp/gccjit_dumps");
let path = &format!("/tmp/gccjit_dumps/{}.c", module.name);
context.set_debug_info(true);
context.dump_to_file(path, true);
}
context.compile_to_file(OutputKind::ObjectFile, obj_out.to_str().expect("path to str"));

View File

@ -126,6 +126,9 @@ pub fn compile_codegen_unit<'tcx>(tcx: TyCtxt<'tcx>, cgu_name: Symbol, supports_
context.add_command_line_option("-fdata-sections");
}
if env::var("CG_GCCJIT_DUMP_TREE_ALL").as_deref() == Ok("1") {
context.add_command_line_option("-fdump-tree-all");
}
if env::var("CG_GCCJIT_DUMP_CODE").as_deref() == Ok("1") {
context.set_dump_code_on_compile(true);
}

View File

@ -858,26 +858,31 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
}
fn gep(&mut self, _typ: Type<'gcc>, ptr: RValue<'gcc>, indices: &[RValue<'gcc>]) -> RValue<'gcc> {
let mut result = ptr;
let ptr_type = ptr.get_type();
let mut pointee_type = ptr.get_type();
// NOTE: we cannot use array indexing here like in inbounds_gep because array indexing is
// always considered in bounds in GCC (TODO(antoyo): to be verified).
// So, we have to cast to a number.
let mut result = self.context.new_bitcast(None, ptr, self.sizet_type);
// FIXME(antoyo): if there were more than 1 index, this code is probably wrong and would
// require dereferencing the pointer.
for index in indices {
result = self.context.new_array_access(None, result, *index).get_address(None).to_rvalue();
pointee_type = pointee_type.get_pointee().expect("pointee type");
let pointee_size = self.context.new_rvalue_from_int(index.get_type(), pointee_type.get_size() as i32);
result = result + self.gcc_int_cast(*index * pointee_size, self.sizet_type);
}
result
self.context.new_bitcast(None, result, ptr_type)
}
fn inbounds_gep(&mut self, _typ: Type<'gcc>, ptr: RValue<'gcc>, indices: &[RValue<'gcc>]) -> RValue<'gcc> {
// FIXME(antoyo): would be safer if doing the same thing (loop) as gep.
// TODO(antoyo): specify inbounds somehow.
match indices.len() {
1 => {
self.context.new_array_access(None, ptr, indices[0]).get_address(None)
},
2 => {
let array = ptr.dereference(None); // TODO(antoyo): assert that first index is 0?
self.context.new_array_access(None, array, indices[1]).get_address(None)
},
_ => unimplemented!(),
// NOTE: array indexing is always considered in bounds in GCC (TODO(antoyo): to be verified).
let mut indices = indices.into_iter();
let index = indices.next().expect("first index in inbounds_gep");
let mut result = self.context.new_array_access(None, ptr, *index);
for index in indices {
result = self.context.new_array_access(None, result, *index);
}
result.get_address(None)
}
fn struct_gep(&mut self, value_type: Type<'gcc>, ptr: RValue<'gcc>, idx: u64) -> RValue<'gcc> {

View File

@ -389,18 +389,22 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
};
self.context.new_comparison(None, op, cmp, self.context.new_rvalue_from_int(self.int_type, limit))
}
else if a_type.get_pointee().is_some() && b_type.get_pointee().is_some() {
// NOTE: gcc cannot compare pointers to different objects, but rustc does that, so cast them to usize.
lhs = self.context.new_bitcast(None, lhs, self.usize_type);
rhs = self.context.new_bitcast(None, rhs, self.usize_type);
self.context.new_comparison(None, op.to_gcc_comparison(), lhs, rhs)
}
else {
let left_type = lhs.get_type();
let right_type = rhs.get_type();
if left_type != right_type {
if a_type != b_type {
// NOTE: because libgccjit cannot compare function pointers.
if left_type.dyncast_function_ptr_type().is_some() && right_type.dyncast_function_ptr_type().is_some() {
if a_type.dyncast_function_ptr_type().is_some() && b_type.dyncast_function_ptr_type().is_some() {
lhs = self.context.new_cast(None, lhs, self.usize_type.make_pointer());
rhs = self.context.new_cast(None, rhs, self.usize_type.make_pointer());
}
// NOTE: hack because we try to cast a vector type to the same vector type.
else if format!("{:?}", left_type) != format!("{:?}", right_type) {
rhs = self.context.new_cast(None, rhs, left_type);
else if format!("{:?}", a_type) != format!("{:?}", b_type) {
rhs = self.context.new_cast(None, rhs, a_type);
}
}
self.context.new_comparison(None, op.to_gcc_comparison(), lhs, rhs)

View File

@ -44,7 +44,7 @@ while [[ $# -gt 0 ]]; do
shift
;;
"--test-rustc")
funcs=(test_rustc)
funcs+=(test_rustc)
shift
;;
"--test-successful-rustc")