Skip to content

Commit 92e6c53

Browse files
committed
libcompiler_builtins: don't codegen dead code call to eh_personality
There was a linker error on 32 bit platforms with optimisations turned off, complaining that there was an undefined reference to "rust_eh_personality", when compiling the rustc_const_math as stage1 artifact. Apparently the compiler_builtins crate includes a call to "rust_eh_personality". If compiled for 64 bits, this call doesn't appear, which explains why the linker error only happens on 32 bit platforms, and optimisations will get it removed on 32 bit as well. There were two origins of the call: 1. A for loop where apparently the compiler wasn't sure whether next() could panic or not, and therefore generated a landing pad for the worst case. The minimal reproducible example is "for _ in 0..sr { }". 2. A default impl of uabs where the compiler apparently wasn't sure either whether iabs() could panic or not. Many thanks to nagisa for contributing the fix. This commit also puts extern "C" to the intrinsics, as this is generally a good thing to do.
1 parent 3e20462 commit 92e6c53

File tree

1 file changed

+31
-24
lines changed
  • src/libcompiler_builtins

1 file changed

+31
-24
lines changed

src/libcompiler_builtins/lib.rs

+31-24
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub mod reimpls {
6666
}
6767

6868
#[export_name="__ashlti3"]
69-
pub extern fn shl(a: u128_, b: u128_) -> u128_ {
69+
pub extern "C" fn shl(a: u128_, b: u128_) -> u128_ {
7070
ashl!(a, b, u128_)
7171
}
7272

@@ -89,7 +89,7 @@ pub mod reimpls {
8989
}
9090

9191
#[export_name="__ashrti3"]
92-
pub extern fn shr(a: i128_, b: i128_) -> i128_ {
92+
pub extern "C" fn shr(a: i128_, b: i128_) -> i128_ {
9393
ashr!(a, b, i128_)
9494
}
9595

@@ -110,13 +110,13 @@ pub mod reimpls {
110110

111111

112112
#[export_name="__lshrti3"]
113-
pub extern fn lshr(a: u128_, b: u128_) -> u128_ {
113+
pub extern "C" fn lshr(a: u128_, b: u128_) -> u128_ {
114114
lshr!(a, b, u128_)
115115
}
116116

117117
#[cfg(stage0)]
118118
#[export_name="__udivmodti4"]
119-
pub extern fn u128_div_mod(n: u128_, d: u128_, rem: *mut u128_) -> u128_ {
119+
pub extern "C" fn u128_div_mod(n: u128_, d: u128_, rem: *mut u128_) -> u128_ {
120120
unsafe {
121121
if !rem.is_null() {
122122
*rem = unchecked_rem(n, d);
@@ -127,7 +127,7 @@ pub mod reimpls {
127127

128128
#[cfg(not(stage0))]
129129
#[export_name="__udivmodti4"]
130-
pub extern fn u128_div_mod(n: u128_, d: u128_, rem: *mut u128_) -> u128_ {
130+
pub extern "C" fn u128_div_mod(n: u128_, d: u128_, rem: *mut u128_) -> u128_ {
131131
// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide
132132
unsafe {
133133
// special cases, X is unknown, K != 0
@@ -261,7 +261,12 @@ pub mod reimpls {
261261
// 1 <= sr <= u64::bits() - 1
262262
let mut carry = 0;
263263

264-
for _ in 0..sr {
264+
// FIXME: replace this with a for loop
265+
// (atm not doable as this generates call to
266+
// eh_personality when optimisations are turned off,
267+
// which in turn gives a linker error in later
268+
// compilation steps)
269+
while sr > 0 {
265270
// r:q = ((r:q) << 1) | carry
266271
r = (r << 1) | (q >> (128 - 1));
267272
q = (q << 1) | carry as u128;
@@ -274,6 +279,7 @@ pub mod reimpls {
274279
let s = (d.wrapping_sub(r).wrapping_sub(1)) as i128 >> (128 - 1);
275280
carry = (s & 1) as u64;
276281
r -= d & s as u128;
282+
sr -= 1;
277283
}
278284

279285
if !rem.is_null() {
@@ -284,7 +290,7 @@ pub mod reimpls {
284290
}
285291

286292
#[export_name="__umodti3"]
287-
pub extern fn u128_mod(a: u128_, b: u128_) -> u128_ {
293+
pub extern "C" fn u128_mod(a: u128_, b: u128_) -> u128_ {
288294
unsafe {
289295
let mut r = ::core::mem::zeroed();
290296
u128_div_mod(a, b, &mut r);
@@ -293,7 +299,7 @@ pub mod reimpls {
293299
}
294300

295301
#[export_name="__modti3"]
296-
pub extern fn i128_mod(a: i128_, b: i128_) -> i128_ {
302+
pub extern "C" fn i128_mod(a: i128_, b: i128_) -> i128_ {
297303
let b = b.uabs();
298304
let sa = a.signum();
299305
let a = a.uabs();
@@ -305,7 +311,7 @@ pub mod reimpls {
305311
}
306312

307313
#[export_name="__divti3"]
308-
pub extern fn i128_div(a: i128_, b: i128_) -> i128_ {
314+
pub extern "C" fn i128_div(a: i128_, b: i128_) -> i128_ {
309315
let sa = a.signum();
310316
let sb = b.signum();
311317
let a = a.uabs();
@@ -319,7 +325,7 @@ pub mod reimpls {
319325
}
320326

321327
#[export_name="__udivti3"]
322-
pub extern fn u128_div(a: u128_, b: u128_) -> u128_ {
328+
pub extern "C" fn u128_div(a: u128_, b: u128_) -> u128_ {
323329
u128_div_mod(a, b, ptr::null_mut())
324330
}
325331

@@ -365,7 +371,7 @@ pub mod reimpls {
365371

366372
// FIXME: i32 here should be c_int.
367373
#[export_name="__muloti4"]
368-
pub extern fn i128_mul_oflow(a: i128_, b: i128_, o: &mut i32) -> i128_ {
374+
pub extern "C" fn i128_mul_oflow(a: i128_, b: i128_, o: &mut i32) -> i128_ {
369375
mulo!(a, b, o, i128_)
370376
}
371377

@@ -465,24 +471,25 @@ pub mod reimpls {
465471

466472
#[cfg(stage0)]
467473
#[export_name="__multi3"]
468-
pub extern fn u128_mul(a: i128_, b: i128_) -> i128_ {
474+
pub extern "C" fn u128_mul(a: i128_, b: i128_) -> i128_ {
469475
(a as i64 * b as i64) as i128_
470476
}
471477

472478
#[cfg(not(stage0))]
473479
#[export_name="__multi3"]
474-
pub extern fn u128_mul(a: i128_, b: i128_) -> i128_ {
480+
pub extern "C" fn u128_mul(a: i128_, b: i128_) -> i128_ {
475481
mul!(a, b, i128_, i64)
476482
}
477483

478484
trait AbsExt: Sized {
479-
fn uabs(self) -> u128_ {
480-
self.iabs() as u128_
481-
}
485+
fn uabs(self) -> u128_;
482486
fn iabs(self) -> i128_;
483487
}
484488

485489
impl AbsExt for i128_ {
490+
fn uabs(self) -> u128_ {
491+
self.iabs() as u128_
492+
}
486493
fn iabs(self) -> i128_ {
487494
((self ^ self).wrapping_sub(self))
488495
}
@@ -550,12 +557,12 @@ pub mod reimpls {
550557
}
551558

552559
#[export_name="__fixunsdfti"]
553-
pub extern fn f64_as_u128(a: f64) -> u128_ {
560+
pub extern "C" fn f64_as_u128(a: f64) -> u128_ {
554561
float_as_unsigned!(a, f64, u128_)
555562
}
556563

557564
#[export_name="__fixunssfti"]
558-
pub extern fn f32_as_u128(a: f32) -> u128_ {
565+
pub extern "C" fn f32_as_u128(a: f32) -> u128_ {
559566
float_as_unsigned!(a, f32, u128_)
560567
}
561568

@@ -582,17 +589,17 @@ pub mod reimpls {
582589
}
583590

584591
#[export_name="__fixdfti"]
585-
pub extern fn f64_as_i128(a: f64) -> i128_ {
592+
pub extern "C" fn f64_as_i128(a: f64) -> i128_ {
586593
float_as_signed!(a, f64, i128_)
587594
}
588595

589596
#[export_name="__fixsfti"]
590-
pub extern fn f32_as_i128(a: f32) -> i128_ {
597+
pub extern "C" fn f32_as_i128(a: f32) -> i128_ {
591598
float_as_signed!(a, f32, i128_)
592599
}
593600

594601
#[export_name="__floattidf"]
595-
pub extern fn i128_as_f64(a: i128_) -> f64 {
602+
pub extern "C" fn i128_as_f64(a: i128_) -> f64 {
596603
match a.signum() {
597604
1 => u128_as_f64(a.uabs()),
598605
0 => 0.0,
@@ -602,7 +609,7 @@ pub mod reimpls {
602609
}
603610

604611
#[export_name="__floattisf"]
605-
pub extern fn i128_as_f32(a: i128_) -> f32 {
612+
pub extern "C" fn i128_as_f32(a: i128_) -> f32 {
606613
match a.signum() {
607614
1 => u128_as_f32(a.uabs()),
608615
0 => 0.0,
@@ -612,7 +619,7 @@ pub mod reimpls {
612619
}
613620

614621
#[export_name="__floatuntidf"]
615-
pub extern fn u128_as_f64(mut a: u128_) -> f64 {
622+
pub extern "C" fn u128_as_f64(mut a: u128_) -> f64 {
616623
use ::core::f64::MANTISSA_DIGITS;
617624
if a == 0 { return 0.0; }
618625
let sd = 128 - a.leading_zeros();
@@ -643,7 +650,7 @@ pub mod reimpls {
643650
}
644651

645652
#[export_name="__floatuntisf"]
646-
pub extern fn u128_as_f32(mut a: u128_) -> f32 {
653+
pub extern "C" fn u128_as_f32(mut a: u128_) -> f32 {
647654
use ::core::f32::MANTISSA_DIGITS;
648655
if a == 0 { return 0.0; }
649656
let sd = 128 - a.leading_zeros();

0 commit comments

Comments
 (0)