Skip to content

Commit 62fedef

Browse files
Add Four Codegen Tests
1 parent 387b245 commit 62fedef

4 files changed

+144
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@ assembly-output: emit-asm
2+
//@ only-x86_64
3+
//@ compile-flags: -O
4+
//! Ensure that indexing a slice with `bool` does not
5+
//! generate any redundant `jmp` and `and` instructions.
6+
//! Discovered in issue #123216.
7+
8+
#![crate_type = "lib"]
9+
10+
#[no_mangle]
11+
fn f(a: u32, b: bool, c: bool, d: &mut [u128; 2]) {
12+
// CHECK-LABEL: f:
13+
// CHECK: testl %esi, %esi
14+
// CHECK: je
15+
// CHECK: xorb %dl, %dil
16+
// CHECK: orb $1, (%rcx)
17+
// CHECK: movzbl %dil, %eax
18+
// CHECK: andl $1, %eax
19+
// CHECK: shll $4, %eax
20+
// CHECK: orb $1, (%rcx,%rax)
21+
// CHECK-NOT: jmp
22+
// CHECK-NOT: andl %dil, $1
23+
// CHECK: retq
24+
let mut a = a & 1 != 0;
25+
if b {
26+
a ^= c;
27+
d[0] |= 1;
28+
}
29+
d[a as usize] |= 1;
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//@ compile-flags: -O
2+
//! Ensure that classifying `FpCategory` based on `usize` compiles to
3+
//! a handful of instructions without any `switch` or branches.
4+
//! This regressed between rustc 1.37 and 1.38 and was discovered
5+
//! in issue #74615.
6+
7+
#![crate_type = "lib"]
8+
9+
use std::num::FpCategory;
10+
11+
fn conv(input: usize) -> FpCategory {
12+
match input {
13+
0b10000000 | 0b00000001 => FpCategory::Infinite,
14+
0b01000000 | 0b00000010 => FpCategory::Normal,
15+
0b00100000 | 0b00000100 => FpCategory::Subnormal,
16+
0b00010000 | 0b00001000 => FpCategory::Zero,
17+
0b100000000 | 0b1000000000 => FpCategory::Nan,
18+
_ => unsafe { std::hint::unreachable_unchecked() },
19+
}
20+
}
21+
22+
#[no_mangle]
23+
pub fn complex_test(input: usize) -> bool {
24+
// CHECK-LABEL: @complex_test(
25+
// CHECK-SAME: i64 noundef [[INPUT:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] {
26+
// CHECK: [[TMP0:%.*]] = tail call
27+
// CHECK: [[DOTOFF:%.*]] = add nsw i64 [[TMP0]], -3
28+
// CHECK: [[SWITCH:%.*]] = icmp ult i64 [[DOTOFF]], 2
29+
// CHECK-NOT: switch i64
30+
// CHECK-NOT: br
31+
// CHECK-NOT: label
32+
// CHECK: ret i1 [[SWITCH]]
33+
//
34+
conv(input) == FpCategory::Zero
35+
}
36+
37+
#[no_mangle]
38+
pub fn simpler_test(input: usize) -> bool {
39+
// CHECK-LABEL: @simpler_test(
40+
// CHECK-SAME: i64 noundef [[INPUT:%.*]]) unnamed_addr #[[ATTR0]] {
41+
// CHECK: [[TMP0:%.*]] = add i64 [[INPUT]], -8
42+
// CHECK: [[SWITCH_AND:%.*]] = and i64 [[TMP0]], -9
43+
// CHECK: [[SWITCH_SELECTCMP:%.*]] = icmp eq i64 [[SWITCH_AND]], 0
44+
// CHECK-NOT: switch i64
45+
// CHECK-NOT: br
46+
// CHECK-NOT: label
47+
// CHECK: ret i1 [[SWITCH_SELECTCMP]]
48+
//
49+
match input {
50+
0b00010000 | 0b00001000 => true,
51+
_ => false,
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//@ compile-flags: -O
2+
//! Ensure that `.get()` on `std::num::NonZero*` types do not
3+
//! check for zero equivalency.
4+
//! Discovered in issue #49572.
5+
6+
#![crate_type = "lib"]
7+
8+
#[no_mangle]
9+
pub fn foo(x: std::num::NonZeroU32) -> bool {
10+
// CHECK-LABEL: @foo(
11+
// CHECK: ret i1 true
12+
x.get() != 0
13+
}
14+
15+
#[no_mangle]
16+
pub fn bar(x: std::num::NonZeroI64) -> bool {
17+
// CHECK-LABEL: @bar(
18+
// CHECK: ret i1 true
19+
x.get() != 0
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//@ compile-flags: -O
2+
//! Ensure that matching on `x % 5` generates an unreachable
3+
//! branch for values greater than 4.
4+
//! Discovered in issue #93514.
5+
6+
#![crate_type = "lib"]
7+
8+
#[no_mangle]
9+
pub unsafe fn parse0(x: usize) -> usize {
10+
// CHECK-LABEL: define noundef i64 @parse0(
11+
// CHECK-SAME: i64 noundef [[X:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] {
12+
// CHECK-NEXT: [[START:.*:]]
13+
// CHECK-NEXT: [[_2:%.*]] = urem i64 [[X]], 5
14+
// CHECK-NEXT: switch i64 [[_2]], label %[[DEFAULT_UNREACHABLE1:.*]] [
15+
// CHECK-NEXT: i64 0, label %[[BB6:.*]]
16+
// CHECK-NEXT: i64 1, label %[[BB5:.*]]
17+
// CHECK-NEXT: i64 2, label %[[BB4:.*]]
18+
// CHECK-NEXT: i64 3, label %[[BB3:.*]]
19+
// CHECK-NEXT: i64 4, label %[[BB2:.*]]
20+
// CHECK-NEXT: ]
21+
// CHECK: [[DEFAULT_UNREACHABLE1]]:
22+
// CHECK-NEXT: unreachable
23+
// CHECK: ret i64
24+
match x % 5 {
25+
0 => f1(x),
26+
1 => f2(x),
27+
2 => f3(x),
28+
3 => f4(x),
29+
4 => f5(x),
30+
_ => eliminate_me(),
31+
}
32+
}
33+
34+
extern "Rust" {
35+
fn eliminate_me() -> usize;
36+
fn f1(x: usize) -> usize;
37+
fn f2(x: usize) -> usize;
38+
fn f3(x: usize) -> usize;
39+
fn f4(x: usize) -> usize;
40+
fn f5(x: usize) -> usize;
41+
}

0 commit comments

Comments
 (0)