Auto merge of #85828 - scottmcm:raw-eq, r=oli-obk
Stop generating `alloca`s & `memcmp` for simple short array equality
Example:
```rust
pub fn demo(x: [u16; 6], y: [u16; 6]) -> bool { x == y }
```
Before:
```llvm
define zeroext i1 `@_ZN10playground4demo17h48537f7eac23948fE(i96` %0, i96 %1) unnamed_addr #0 {
start:
%y = alloca [6 x i16], align 8
%x = alloca [6 x i16], align 8
%.0..sroa_cast = bitcast [6 x i16]* %x to i96*
store i96 %0, i96* %.0..sroa_cast, align 8
%.0..sroa_cast3 = bitcast [6 x i16]* %y to i96*
store i96 %1, i96* %.0..sroa_cast3, align 8
%_11.i.i.i = bitcast [6 x i16]* %x to i8*
%_14.i.i.i = bitcast [6 x i16]* %y to i8*
%bcmp.i.i.i = call i32 `@bcmp(i8*` nonnull dereferenceable(12) %_11.i.i.i, i8* nonnull dereferenceable(12) %_14.i.i.i, i64 12) #2, !alias.scope !2
%2 = icmp eq i32 %bcmp.i.i.i, 0
ret i1 %2
}
```
```x86
playground::demo: # `@playground::demo`
sub rsp, 32
mov qword ptr [rsp], rdi
mov dword ptr [rsp + 8], esi
mov qword ptr [rsp + 16], rdx
mov dword ptr [rsp + 24], ecx
xor rdi, rdx
xor esi, ecx
or rsi, rdi
sete al
add rsp, 32
ret
```
After:
```llvm
define zeroext i1 `@_ZN4mini4demo17h7a8994aaa314c981E(i96` %0, i96 %1) unnamed_addr #0 {
start:
%2 = icmp eq i96 %0, %1
ret i1 %2
}
```
```x86
_ZN4mini4demo17h7a8994aaa314c981E:
xor rcx, r8
xor edx, r9d
or rdx, rcx
sete al
ret
```
This commit is contained in:
commit
ee86f96ba1
15 changed files with 410 additions and 114 deletions
11
src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.rs
Normal file
11
src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#![feature(core_intrinsics)]
|
||||
#![feature(const_intrinsic_raw_eq)]
|
||||
#![deny(const_err)]
|
||||
|
||||
const BAD_RAW_EQ_CALL: bool = unsafe {
|
||||
std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16))
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
};
|
||||
|
||||
pub fn main() {
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/intrinsic-raw_eq-const-padding.rs:6:5
|
||||
|
|
||||
LL | std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading 4 bytes of memory starting at alloc2, but 1 byte is uninitialized starting at alloc2+0x1, and this operation requires initialized memory
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
27
src/test/ui/intrinsics/intrinsic-raw_eq-const.rs
Normal file
27
src/test/ui/intrinsics/intrinsic-raw_eq-const.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(const_intrinsic_raw_eq)]
|
||||
#![deny(const_err)]
|
||||
|
||||
pub fn main() {
|
||||
use std::intrinsics::raw_eq;
|
||||
|
||||
const RAW_EQ_I32_TRUE: bool = unsafe { raw_eq(&42_i32, &42) };
|
||||
assert!(RAW_EQ_I32_TRUE);
|
||||
|
||||
const RAW_EQ_I32_FALSE: bool = unsafe { raw_eq(&4_i32, &2) };
|
||||
assert!(!RAW_EQ_I32_FALSE);
|
||||
|
||||
const RAW_EQ_CHAR_TRUE: bool = unsafe { raw_eq(&'a', &'a') };
|
||||
assert!(RAW_EQ_CHAR_TRUE);
|
||||
|
||||
const RAW_EQ_CHAR_FALSE: bool = unsafe { raw_eq(&'a', &'A') };
|
||||
assert!(!RAW_EQ_CHAR_FALSE);
|
||||
|
||||
const RAW_EQ_ARRAY_TRUE: bool = unsafe { raw_eq(&[13_u8, 42], &[13, 42]) };
|
||||
assert!(RAW_EQ_ARRAY_TRUE);
|
||||
|
||||
const RAW_EQ_ARRAY_FALSE: bool = unsafe { raw_eq(&[13_u8, 42], &[42, 13]) };
|
||||
assert!(!RAW_EQ_ARRAY_FALSE);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue