Change:
uses , and declares it to return i32, in reality it returns c_int, so this is a potential portability concern. Maybe memcmp can be made an intrinsic to resolve this.
It also takes a parameter, not a .
Neither of these are a practical issue (yet). crate libc does not support any other configuration than so far.
cc
The extern function is now in
What should we do next? Should we try to create a intrinsic?
Hi, I believe this issue is causing array comparisons on the AVR architecture to break (see the linked issue, ). Is there any consensus on a path forward here?

Discussion:
self.const_uint(self.type_i1(), val as u64) } <ins> fn const_i16(&self, i: i16) -> RValue<'gcc> { self.const_int(self.type_i16(), i as i64) } </ins> fn const_i32(&self, i: i32) -> RValue<'gcc> { self.const_int(self.type_i32(), i as i64) }

self.const_uint(self.type_i1(), val as u64) } <ins> fn const_i16(&self, i: i16) -> &'ll Value { self.const_int(self.type_i16(), i as i64) } </ins> fn const_i32(&self, i: i32) -> &'ll Value { self.const_int(self.type_i32(), i as i64) }

// This isn't an "LLVM intrinsic", but LLVM's optimization passes // recognize it like one and we assume it exists in `core::slice::cmp` <del> ifn!("memcmp", fn(i8p, i8p, t_isize) -> t_i32); </del> <ins> 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), } </ins> // variadic intrinsics ifn!("llvm.va_start", fn(i8p) -> void);

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]); <del> self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0)) </del> <ins> 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)), } </ins> } }

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; <ins> fn const_i16(&self, i: i16) -> Self::Value; </ins> fn const_i32(&self, i: i32) -> Self::Value; fn const_u32(&self, i: u32) -> Self::Value; fn const_u64(&self, i: u64) -> Self::Value;

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; } <ins> #[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")))] </ins> 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;

//! Comparison traits for `[T]`. use crate::cmp::{self, Ordering}; <ins> use crate::ffi; </ins> use crate::mem; use super::from_raw_parts;

/// /// Returns 0 for equal, < 0 for less than and > 0 for greater /// than. <del> // FIXME(#32610): Return type should be c_int fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32; </del> <ins> fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> ffi::c_int; </ins> } #[stable(feature = "rust1", since = "1.0.0")]