Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 6693595

Browse files
authored
Add missing cast and change some bitcasts to casts to avoid a gimple verification failure (rust-lang#100)
1 parent cd4810d commit 6693595

File tree

3 files changed

+35
-23
lines changed

3 files changed

+35
-23
lines changed

Readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ Or add a breakpoint to `add_error` in gdb and print the line number using:
111111
p loc->m_line
112112
```
113113
114+
To get the `rustc` command to run in `gdb`, add the `--verbose` flag to `cargo build`.
115+
114116
### How to use a custom-build rustc
115117
116118
* Build the stage2 compiler (`rustup toolchain link debug-current build/x86_64-unknown-linux-gnu/stage2`).

src/back/write.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::fs;
1+
use std::{env, fs};
22

33
use gccjit::OutputKind;
44
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
@@ -42,17 +42,17 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<GccCodegenBackend>, _diag_han
4242
let _timer = cgcx
4343
.prof
4444
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
45-
match &*module.name {
46-
"std_example.7rcbfp3g-cgu.15" => {
47-
println!("Dumping reproducer {}", module.name);
48-
let _ = fs::create_dir("/tmp/reproducers");
49-
// FIXME(antoyo): segfault in dump_reproducer_to_file() might be caused by
50-
// transmuting an rvalue to an lvalue.
51-
// Segfault is actually in gcc::jit::reproducer::get_identifier_as_lvalue
52-
context.dump_reproducer_to_file(&format!("/tmp/reproducers/{}.c", module.name));
53-
println!("Dumped reproducer {}", module.name);
54-
},
55-
_ => (),
45+
if env::var("CG_GCCJIT_DUMP_MODULE_NAMES").as_deref() == Ok("1") {
46+
println!("Module {}", module.name);
47+
}
48+
if env::var("CG_GCCJIT_DUMP_MODULE").as_deref() == Ok(&module.name) {
49+
println!("Dumping reproducer {}", module.name);
50+
let _ = fs::create_dir("/tmp/reproducers");
51+
// FIXME(antoyo): segfault in dump_reproducer_to_file() might be caused by
52+
// transmuting an rvalue to an lvalue.
53+
// Segfault is actually in gcc::jit::reproducer::get_identifier_as_lvalue
54+
context.dump_reproducer_to_file(&format!("/tmp/reproducers/{}.c", module.name));
55+
println!("Dumped reproducer {}", module.name);
5656
}
5757
context.compile_to_file(OutputKind::ObjectFile, obj_out.to_str().expect("path to str"));
5858
}

src/intrinsic/mod.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
525525

526526
let value =
527527
if result_type.is_signed(self.cx) {
528-
self.context.new_bitcast(None, value, typ)
528+
self.context.new_cast(None, value, typ)
529529
}
530530
else {
531531
value
@@ -689,7 +689,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
689689
},
690690
};
691691

692-
self.context.new_bitcast(None, result, result_type)
692+
self.context.new_cast(None, result, result_type)
693693
}
694694

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

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

@@ -763,7 +768,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
763768
let arg =
764769
if result_type.is_signed(self.cx) {
765770
let new_type = result_type.to_unsigned(self.cx);
766-
self.context.new_bitcast(None, arg, new_type)
771+
self.context.new_cast(None, arg, new_type)
767772
}
768773
else {
769774
arg
@@ -815,10 +820,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
815820
let not_high = self.context.new_unary_op(None, UnaryOp::LogicalNegate, self.u64_type, high);
816821
let not_low_and_not_high = not_low & not_high;
817822
let index = not_low + not_low_and_not_high;
823+
// NOTE: the following cast is necessary to avoid a GIMPLE verification failure in
824+
// gcc.
825+
// TODO(antoyo): do the correct verification in libgccjit to avoid an error at the
826+
// compilation stage.
827+
let index = self.context.new_cast(None, index, self.i32_type);
818828

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

821-
return self.context.new_bitcast(None, res, result_type);
831+
return self.context.new_cast(None, res, result_type);
822832
}
823833
else {
824834
unimplemented!("count_trailing_zeroes for {:?}", arg_type);
@@ -832,7 +842,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
832842
arg
833843
};
834844
let res = self.context.new_call(None, count_trailing_zeroes, &[arg]);
835-
self.context.new_bitcast(None, res, result_type)
845+
self.context.new_cast(None, res, result_type)
836846
}
837847

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

847857
let value =
848858
if result_type.is_signed(self.cx) {
849-
self.context.new_bitcast(None, value, value_type)
859+
self.context.new_cast(None, value, value_type)
850860
}
851861
else {
852862
value
@@ -862,7 +872,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
862872
let low = self.context.new_cast(None, value, self.cx.ulonglong_type);
863873
let low = self.context.new_call(None, popcount, &[low]);
864874
let res = high + low;
865-
return self.context.new_bitcast(None, res, result_type);
875+
return self.context.new_cast(None, res, result_type);
866876
}
867877

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

889899
if value_type.is_u8(&self.cx) {
890-
return self.context.new_bitcast(None, value, result_type);
900+
return self.context.new_cast(None, value, result_type);
891901
}
892902

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

900910
if value_type.is_u16(&self.cx) {
901-
return self.context.new_bitcast(None, value, result_type);
911+
return self.context.new_cast(None, value, result_type);
902912
}
903913

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

911921
if value_type.is_u32(&self.cx) {
912-
return self.context.new_bitcast(None, value, result_type);
922+
return self.context.new_cast(None, value, result_type);
913923
}
914924

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

922-
self.context.new_bitcast(None, value, result_type)
932+
self.context.new_cast(None, value, result_type)
923933
}
924934

925935
// Algorithm from: https://blog.regehr.org/archives/1063

0 commit comments

Comments
 (0)