From aa670166243e264985f95a21490f92c91addf48c Mon Sep 17 00:00:00 2001 From: David Morrison Date: Wed, 10 Nov 2021 20:14:23 -0800 Subject: [PATCH] make memcmp return a value of c_int_width instead of i32 --- compiler/rustc_codegen_gcc/src/common.rs | 4 ++++ compiler/rustc_codegen_llvm/src/common.rs | 4 ++++ compiler/rustc_codegen_llvm/src/context.rs | 5 ++++- compiler/rustc_codegen_llvm/src/intrinsic.rs | 5 ++++- compiler/rustc_codegen_ssa/src/traits/consts.rs | 1 + library/core/src/ffi/mod.rs | 3 +++ library/core/src/slice/cmp.rs | 4 ++-- 7 files changed, 22 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 61709dd92de..19127c7612d 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -91,6 +91,10 @@ fn const_bool(&self, val: bool) -> RValue<'gcc> { self.const_uint(self.type_i1(), val as u64) } + fn const_i16(&self, i: i16) -> RValue<'gcc> { + self.const_int(self.type_i16(), i as i64) + } + fn const_i32(&self, i: i32) -> RValue<'gcc> { self.const_int(self.type_i32(), i as i64) } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index b10e74625da..a85b2e6141b 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -147,6 +147,10 @@ fn const_bool(&self, val: bool) -> &'ll Value { self.const_uint(self.type_i1(), val as u64) } + fn const_i16(&self, i: i16) -> &'ll Value { + self.const_int(self.type_i16(), i as i64) + } + fn const_i32(&self, i: i32) -> &'ll Value { self.const_int(self.type_i32(), i as i64) } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 2b76bfdb5ec..712431ca9ae 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -859,7 +859,10 @@ macro_rules! mk_struct { // This isn't an "LLVM intrinsic", but LLVM's optimization passes // recognize it like one and we assume it exists in `core::slice::cmp` - ifn!("memcmp", fn(i8p, i8p, t_isize) -> t_i32); + match self.sess().target.arch.as_str() { + "avr" | "msp430" => ifn!("memcmp", fn(i8p, i8p, t_isize) -> t_i16), + _ => ifn!("memcmp", fn(i8p, i8p, t_isize) -> t_i32), + } // variadic intrinsics ifn!("llvm.va_start", fn(i8p) -> void); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 10df671baa2..fe149b4c8c2 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -329,7 +329,10 @@ fn codegen_intrinsic_call( let b_ptr = self.bitcast(b, i8p_ty); let n = self.const_usize(layout.size().bytes()); let cmp = self.call_intrinsic("memcmp", &[a_ptr, b_ptr, n]); - self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0)) + match self.cx.sess().target.arch.as_str() { + "avr" | "msp430" => self.icmp(IntPredicate::IntEQ, cmp, self.const_i16(0)), + _ => self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0)), + } } } diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index 918f3684169..c3519a24d53 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -13,6 +13,7 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn const_uint(&self, t: Self::Type, i: u64) -> Self::Value; fn const_uint_big(&self, t: Self::Type, u: u128) -> Self::Value; fn const_bool(&self, val: bool) -> Self::Value; + fn const_i16(&self, i: i16) -> Self::Value; fn const_i32(&self, i: i32) -> Self::Value; fn const_u32(&self, i: u32) -> Self::Value; fn const_u64(&self, i: u64) -> Self::Value; diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 2b611e5aae2..e61ea9ce87f 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -57,6 +57,9 @@ macro_rules! type_alias { type_alias! { "c_uchar.md", c_uchar = u8, NonZero_c_uchar = NonZeroU8; } type_alias! { "c_short.md", c_short = i16, NonZero_c_short = NonZeroI16; } type_alias! { "c_ushort.md", c_ushort = u16, NonZero_c_ushort = NonZeroU16; } +#[cfg(any(target_arch = "avr", target_arch = "msp430"))] +type_alias! { "c_int.md", c_int = i16, NonZero_c_int = NonZeroI16; } +#[cfg(not(any(target_arch = "avr", target_arch = "msp430")))] type_alias! { "c_int.md", c_int = i32, NonZero_c_int = NonZeroI32; } type_alias! { "c_uint.md", c_uint = u32, NonZero_c_uint = NonZeroU32; } type_alias! { "c_long.md", c_long = i32, NonZero_c_long = NonZeroI32; diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 27c6b6f5bc0..5e1b218e507 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -1,6 +1,7 @@ //! Comparison traits for `[T]`. use crate::cmp::{self, Ordering}; +use crate::ffi; use crate::mem; use super::from_raw_parts; @@ -13,8 +14,7 @@ /// /// Returns 0 for equal, < 0 for less than and > 0 for greater /// than. - // FIXME(#32610): Return type should be c_int - fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32; + fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> ffi::c_int; } #[stable(feature = "rust1", since = "1.0.0")]