Skip to content

Commit 841ffe6

Browse files
authored
Merge pull request #22 from antoyo/fix-align-128bits
Fix alignment for 128-bit integers
2 parents 56fda23 + 93f3d3b commit 841ffe6

File tree

7 files changed

+111
-48
lines changed

7 files changed

+111
-48
lines changed

gcc-test-backend/Cargo.lock

Lines changed: 1 addition & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gcc-test-backend/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ edition = "2018"
99
#mini_core = { path = "mini_core" }
1010
#deflate = "0.7.19"
1111
#backtrace = "0.3.57"
12-
mylib = { path = "mylib" }
12+
#mylib = { path = "mylib" }
1313

1414
[profile.dev]
1515
panic = "abort"

gcc-test-backend/src/main.rs

Lines changed: 91 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(const_option)]
1+
#![feature(const_option, core_intrinsics)]
22

33
fn main() {
44
/*test_float!(f64, f64, f64::INFINITY, f64::NEG_INFINITY, f64::NAN);
@@ -193,47 +193,104 @@ fn main() {
193193
assert_eq!(r.saturating_pow(3), -8 as i128);
194194
assert_eq!(r.saturating_pow(0), 1 as i128);*/
195195

196-
{
197-
const A: u128 = 0b0101100;
198-
const B: u128 = 0b0100001;
199-
const C: u128 = 0b1111001;
196+
/*let res = 10_i64.checked_div(2);
197+
if res == Some(5) {
198+
println!("1");
199+
}*/
200200

201-
const _0: u128 = 0;
202-
const _1: u128 = !0;
203-
204-
assert_eq!(A.reverse_bits().reverse_bits(), A);
205-
assert_eq!(B.reverse_bits().reverse_bits(), B);
206-
assert_eq!(C.reverse_bits().reverse_bits(), C);
207-
208-
// Swapping these should make no difference
209-
assert_eq!(_0.reverse_bits(), _0);
210-
assert_eq!(_1.reverse_bits(), _1);
201+
fn equal(num1: &Option<i64>, num2: &Option<i64>) -> bool {
202+
match (num1, num2) {
203+
(Some(num1), Some(num2)) => num1 == num2,
204+
(None, None) => true,
205+
_ => false
206+
}
211207
}
212208

213-
const _0: i128 = 0;
214-
const _1: i128 = !0;
215-
216-
use std::i128::MAX;
209+
fn equal2(num1: &Option<i128>, num2: &Option<i128>) -> bool {
210+
match (num1, num2) {
211+
(Some(num1), Some(num2)) => num1 == num2,
212+
(None, None) => true,
213+
_ => false
214+
}
215+
}
217216

218-
let a: i128 = 0b0101_1111;
219-
assert_eq!(a.trailing_ones(), 5);
220-
assert_eq!((!a).leading_ones(), i128::BITS - 7);
217+
/*let res2 = Some(10_i64 / 2);
218+
// NOTE: (local variable case) res2 is initialized as:
219+
// first 8 bits: 1
220+
// next 8 bits : 5
221+
//
222+
// (global variable case) Some(5) is initialized as:
223+
// first 8 bits: 1
224+
// next 8 bits : 5
225+
if equal(&res2, &Some(5)) {
226+
//println!("Equal: {}", res2 == Some(5));
227+
std::process::exit(1);
228+
}*/
229+
230+
// TODO: this seems to confirm that align(i128) == 16.
231+
#[repr(C)]
232+
struct int_option {
233+
is_some: bool,
234+
val: i128,
235+
}
221236

222-
assert_eq!(a.reverse_bits().leading_ones(), 5);
237+
fn equal3(int1: &int_option, int2: &int_option) -> bool {
238+
int1.is_some == int2.is_some &&
239+
int1.val == int2.val
240+
}
223241

224-
assert_eq!(_1.leading_ones(), i128::BITS);
225-
assert_eq!(_1.trailing_ones(), i128::BITS);
242+
let res = int_option {
243+
is_some: true,
244+
val: 10 / 2,
245+
};
246+
247+
let expected = int_option {
248+
is_some: true,
249+
val: 5,
250+
};
251+
252+
/*if equal3(&expected, &res) {
253+
std::process::exit(50);
254+
}*/
255+
256+
// FIXME: &Option<i128> does not work while Option<i128> does.
257+
let res2 = Some(10_i128 / 2);
258+
// NOTE: (local variable case) res2 is initialized as:
259+
// first 16 bits: 1 (garbage in the last 8 bits)
260+
// next 8 bits : 5
261+
// next 8 bits : 0
262+
//
263+
// FIXME: maybe there's an alignment problem (i.e. the i128 wants to be aligned on 128-bits?).
264+
//
265+
// (global variable case) Some(5) is initialized as:
266+
// first 8 bits: 1
267+
// next 8 bits : 5
268+
// next 8 bits : 0
269+
//
270+
//let res1 = Some(5); // NOTE: It works when putting the value in a variable.
271+
// NOTE: the case that doesn't work uses a global variable, which might mean we don't
272+
// initialize them correctly.
273+
if equal2(&Some(5), &res2) {
274+
//println!("Equal: {}", res2 == Some(5));
275+
std::process::exit(42);
276+
}
226277

227-
assert_eq!((_1 << 1).trailing_ones(), 0);
228-
assert_eq!(MAX.leading_ones(), 0);
278+
/*let res = 10_i128.checked_div(2);
279+
if res == Some(5) {
280+
println!("2");
281+
}
282+
if let Some(val) = res {
283+
println!("Val: {}", val);
284+
}*/
229285

230-
assert_eq!((_1 << 1).leading_ones(), i128::BITS - 1);
231-
assert_eq!(MAX.trailing_ones(), i128::BITS - 1);
286+
/*let res = 5_i128.checked_div(0);
287+
if let Some(val) = res {
288+
println!("Val: {}", val);
289+
}
232290
233-
assert_eq!(_0.leading_ones(), 0);
234-
assert_eq!(_0.trailing_ones(), 0);
291+
assert!((10 as i128).checked_div(2) == Some(5));
292+
assert!((5 as i128).checked_div(0) == None);*/
235293

236-
let x: i128 = 0b0010_1100;
237-
assert_eq!(x.leading_ones(), 0);
238-
assert_eq!(x.trailing_ones(), 0);
294+
/*assert_eq!((10 as i128).checked_div(2), Some(5));
295+
assert_eq!((5 as i128).checked_div(0), None);*/
239296
}

src/base.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::env;
12
use std::sync::Once;
23
use std::time::Instant;
34

@@ -75,7 +76,9 @@ pub fn compile_codegen_unit<'tcx>(tcx: TyCtxt<'tcx>, cgu_name: Symbol) -> (Modul
7576
// TODO: only set on x86 platforms.
7677
context.add_command_line_option("-masm=intel");
7778
//context.set_dump_code_on_compile(true);
78-
//context.set_dump_initial_gimple(true);
79+
if env::var("CG_GCCJIT_DUMP_GIMPLE").as_deref() == Ok("1") {
80+
context.set_dump_initial_gimple(true);
81+
}
7982
context.set_debug_info(true);
8083
//context.set_dump_everything(true);
8184
//context.set_keep_intermediates(true);

src/builder.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,15 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
874874
}
875875

876876
fn alloca(&mut self, ty: Type<'gcc>, align: Align) -> RValue<'gcc> {
877-
let aligned_type = ty.get_aligned(align.bytes());
877+
// FIXME: this check that we don't call get_aligned() a second time on a time.
878+
// Ideally, we shouldn't need to do this check.
879+
let aligned_type =
880+
if ty == self.cx.u128_type || ty == self.cx.i128_type {
881+
ty
882+
}
883+
else {
884+
ty.get_aligned(align.bytes())
885+
};
878886
// TODO: It might be better to return a LValue, but fixing the rustc API is non-trivial.
879887
self.stack_var_count.set(self.stack_var_count.get() + 1);
880888
self.current_func().new_local(None, aligned_type, &format!("stack_var_{}", self.stack_var_count.get())).get_address(None)

src/common.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::convert::TryFrom;
22
use std::convert::TryInto;
33

4-
use gccjit::{Block, RValue, Type, ToRValue};
4+
use gccjit::{Block, CType, RValue, Type, ToRValue};
55
use rustc_codegen_ssa::mir::place::PlaceRef;
66
use rustc_codegen_ssa::traits::{
77
BaseTypeMethods,
@@ -425,11 +425,11 @@ impl<'gcc, 'tcx> TypeReflection<'gcc, 'tcx> for Type<'gcc> {
425425
}
426426

427427
fn is_i128(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool {
428-
self.unqualified() == cx.i128_type
428+
self.unqualified() == cx.context.new_c_type(CType::Int128t)
429429
}
430430

431431
fn is_u128(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool {
432-
self.unqualified() == cx.u128_type
432+
self.unqualified() == cx.context.new_c_type(CType::UInt128t)
433433
}
434434

435435
fn is_f32(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool {

src/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,12 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
145145
let i16_type = context.new_type::<i16>();
146146
let i32_type = context.new_type::<i32>();
147147
let i64_type = context.new_c_type(CType::LongLong);
148-
let i128_type = context.new_c_type(CType::Int128t);
148+
let i128_type = context.new_c_type(CType::Int128t).get_aligned(8); // TODO: should this be hard-coded?
149149
let u8_type = context.new_type::<u8>();
150150
let u16_type = context.new_type::<u16>();
151151
let u32_type = context.new_type::<u32>();
152152
let u64_type = context.new_c_type(CType::ULongLong);
153-
let u128_type = context.new_c_type(CType::UInt128t);
153+
let u128_type = context.new_c_type(CType::UInt128t).get_aligned(8); // TODO: should this be hard-coded?
154154

155155
let tls_model = to_gcc_tls_mode(tcx.sess.tls_model());
156156

0 commit comments

Comments
 (0)