Add missing cast and change some bitcasts to casts to avoid a gimple verification failure (#100)
This commit is contained in:
parent
cd4810de42
commit
669359530e
3 changed files with 35 additions and 23 deletions
|
@ -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`).
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::fs;
|
||||
use std::{env, fs};
|
||||
|
||||
use gccjit::OutputKind;
|
||||
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
|
||||
|
@ -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"));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -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> {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue