Skip to content

Commit

Permalink
Add missing cast and change some bitcasts to casts to avoid a gimple …
Browse files Browse the repository at this point in the history
…verification failure (#100)
  • Loading branch information
antoyo committed Oct 11, 2021
1 parent cd4810d commit 6693595
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 23 deletions.
2 changes: 2 additions & 0 deletions Readme.md
Expand Up @@ -111,6 +111,8 @@ Or add a breakpoint to `add_error` in gdb and print the line number using:
p loc->m_line
```
To get the `rustc` command to run in `gdb`, add the `--verbose` flag to `cargo build`.
### How to use a custom-build rustc
* Build the stage2 compiler (`rustup toolchain link debug-current build/x86_64-unknown-linux-gnu/stage2`).
Expand Down
24 changes: 12 additions & 12 deletions src/back/write.rs
@@ -1,4 +1,4 @@
use std::fs;
use std::{env, fs};

use gccjit::OutputKind;
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
Expand Down Expand Up @@ -42,17 +42,17 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<GccCodegenBackend>, _diag_han
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
match &*module.name {
"std_example.7rcbfp3g-cgu.15" => {
println!("Dumping reproducer {}", module.name);
let _ = fs::create_dir("/tmp/reproducers");
// FIXME(antoyo): segfault in dump_reproducer_to_file() might be caused by
// transmuting an rvalue to an lvalue.
// Segfault is actually in gcc::jit::reproducer::get_identifier_as_lvalue
context.dump_reproducer_to_file(&format!("/tmp/reproducers/{}.c", module.name));
println!("Dumped reproducer {}", module.name);
},
_ => (),
if env::var("CG_GCCJIT_DUMP_MODULE_NAMES").as_deref() == Ok("1") {
println!("Module {}", module.name);
}
if env::var("CG_GCCJIT_DUMP_MODULE").as_deref() == Ok(&module.name) {
println!("Dumping reproducer {}", module.name);
let _ = fs::create_dir("/tmp/reproducers");
// FIXME(antoyo): segfault in dump_reproducer_to_file() might be caused by
// transmuting an rvalue to an lvalue.
// Segfault is actually in gcc::jit::reproducer::get_identifier_as_lvalue
context.dump_reproducer_to_file(&format!("/tmp/reproducers/{}.c", module.name));
println!("Dumped reproducer {}", module.name);
}
context.compile_to_file(OutputKind::ObjectFile, obj_out.to_str().expect("path to str"));
}
Expand Down
32 changes: 21 additions & 11 deletions src/intrinsic/mod.rs
Expand Up @@ -525,7 +525,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {

let value =
if result_type.is_signed(self.cx) {
self.context.new_bitcast(None, value, typ)
self.context.new_cast(None, value, typ)
}
else {
value
Expand Down Expand Up @@ -689,7 +689,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
},
};

self.context.new_bitcast(None, result, result_type)
self.context.new_cast(None, result, result_type)
}

fn count_leading_zeroes(&self, width: u64, arg: RValue<'gcc>) -> RValue<'gcc> {
Expand Down Expand Up @@ -740,6 +740,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let not_low = self.context.new_unary_op(None, UnaryOp::LogicalNegate, self.u64_type, low);
let not_low_and_not_high = not_low & not_high;
let index = not_high + not_low_and_not_high;
// NOTE: the following cast is necessary to avoid a GIMPLE verification failure in
// gcc.
// TODO(antoyo): do the correct verification in libgccjit to avoid an error at the
// compilation stage.
let index = self.context.new_cast(None, index, self.i32_type);

let res = self.context.new_array_access(None, result, index);

Expand All @@ -763,7 +768,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let arg =
if result_type.is_signed(self.cx) {
let new_type = result_type.to_unsigned(self.cx);
self.context.new_bitcast(None, arg, new_type)
self.context.new_cast(None, arg, new_type)
}
else {
arg
Expand Down Expand Up @@ -815,10 +820,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let not_high = self.context.new_unary_op(None, UnaryOp::LogicalNegate, self.u64_type, high);
let not_low_and_not_high = not_low & not_high;
let index = not_low + not_low_and_not_high;
// NOTE: the following cast is necessary to avoid a GIMPLE verification failure in
// gcc.
// TODO(antoyo): do the correct verification in libgccjit to avoid an error at the
// compilation stage.
let index = self.context.new_cast(None, index, self.i32_type);

let res = self.context.new_array_access(None, result, index);

return self.context.new_bitcast(None, res, result_type);
return self.context.new_cast(None, res, result_type);
}
else {
unimplemented!("count_trailing_zeroes for {:?}", arg_type);
Expand All @@ -832,7 +842,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
arg
};
let res = self.context.new_call(None, count_trailing_zeroes, &[arg]);
self.context.new_bitcast(None, res, result_type)
self.context.new_cast(None, res, result_type)
}

fn int_width(&self, typ: Type<'gcc>) -> i64 {
Expand All @@ -846,7 +856,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {

let value =
if result_type.is_signed(self.cx) {
self.context.new_bitcast(None, value, value_type)
self.context.new_cast(None, value, value_type)
}
else {
value
Expand All @@ -862,7 +872,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let low = self.context.new_cast(None, value, self.cx.ulonglong_type);
let low = self.context.new_call(None, popcount, &[low]);
let res = high + low;
return self.context.new_bitcast(None, res, result_type);
return self.context.new_cast(None, res, result_type);
}

// First step.
Expand All @@ -887,7 +897,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let value = left + right;

if value_type.is_u8(&self.cx) {
return self.context.new_bitcast(None, value, result_type);
return self.context.new_cast(None, value, result_type);
}

// Fourth step.
Expand All @@ -898,7 +908,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let value = left + right;

if value_type.is_u16(&self.cx) {
return self.context.new_bitcast(None, value, result_type);
return self.context.new_cast(None, value, result_type);
}

// Fifth step.
Expand All @@ -909,7 +919,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let value = left + right;

if value_type.is_u32(&self.cx) {
return self.context.new_bitcast(None, value, result_type);
return self.context.new_cast(None, value, result_type);
}

// Sixth step.
Expand All @@ -919,7 +929,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let right = shifted & mask;
let value = left + right;

self.context.new_bitcast(None, value, result_type)
self.context.new_cast(None, value, result_type)
}

// Algorithm from: https://blog.regehr.org/archives/1063
Expand Down

0 comments on commit 6693595

Please sign in to comment.