Skip to content

Commit

Permalink
Auto merge of rust-lang#134626 - veera-sivarajan:five-codegen-tests, …
Browse files Browse the repository at this point in the history
…r=Mark-Simulacrum

Add Four Codegen Tests

Closes rust-lang#74615
Closes rust-lang#123216
Closes rust-lang#49572
Closes rust-lang#93514

This PR adds four codegen tests. The FileCheck assertions were generated with the help of `update_test_checks.py` and `update_llc_test_checks.py` from the LLVM project.
  • Loading branch information
bors committed Jan 19, 2025
2 parents 39dc268 + c00d7e2 commit 816104f
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
31 changes: 31 additions & 0 deletions tests/assembly/indexing-with-bools-no-redundant-instructions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//@ assembly-output: emit-asm
//@ only-x86_64
//@ ignore-sgx Test incompatible with LVI mitigations
//@ compile-flags: -O
//! Ensure that indexing a slice with `bool` does not
//! generate any redundant `jmp` and `and` instructions.
//! Discovered in issue #123216.
#![crate_type = "lib"]

#[no_mangle]
fn f(a: u32, b: bool, c: bool, d: &mut [u128; 2]) {
// CHECK-LABEL: f:
// CHECK: testl %esi, %esi
// CHECK: je
// CHECK: xorb %dl, %dil
// CHECK: orb $1, (%rcx)
// CHECK: movzbl %dil, %eax
// CHECK: andl $1, %eax
// CHECK: shll $4, %eax
// CHECK: orb $1, (%rcx,%rax)
// CHECK-NOT: jmp
// CHECK-NOT: andl %dil, $1
// CHECK: retq
let mut a = a & 1 != 0;
if b {
a ^= c;
d[0] |= 1;
}
d[a as usize] |= 1;
}
53 changes: 53 additions & 0 deletions tests/codegen/classify-fp-category-of-usize-without-branch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//@ compile-flags: -O
//! Ensure that classifying `FpCategory` based on `usize` compiles to
//! a handful of instructions without any `switch` or branches.
//! This regressed between rustc 1.37 and 1.38 and was discovered
//! in issue #74615.
#![crate_type = "lib"]

use std::num::FpCategory;

fn conv(input: u32) -> FpCategory {
match input {
0b10000000 | 0b00000001 => FpCategory::Infinite,
0b01000000 | 0b00000010 => FpCategory::Normal,
0b00100000 | 0b00000100 => FpCategory::Subnormal,
0b00010000 | 0b00001000 => FpCategory::Zero,
0b100000000 | 0b1000000000 => FpCategory::Nan,
_ => unsafe { std::hint::unreachable_unchecked() },
}
}

#[no_mangle]
pub fn complex_test(input: u32) -> bool {
// CHECK-LABEL: @complex_test(
// CHECK-SAME: i32 noundef [[INPUT:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK: [[TMP0:%.*]] = tail call
// CHECK: [[DOTOFF:%.*]] = add nsw i32 [[TMP0]], -3
// CHECK: [[SWITCH:%.*]] = icmp ult i32 [[DOTOFF]], 2
// CHECK-NOT: switch i32
// CHECK-NOT: br
// CHECK-NOT: label
// CHECK: ret i1 [[SWITCH]]
//
conv(input) == FpCategory::Zero
}

#[no_mangle]
pub fn simpler_test(input: u32) -> bool {
// CHECK-LABEL: @simpler_test(
// CHECK-SAME: i32 noundef [[INPUT:%.*]]) unnamed_addr #[[ATTR0]] {
// CHECK: [[TMP0:%.*]] = add i32 [[INPUT]], -8
// CHECK: [[SWITCH_AND:%.*]] = and i32 [[TMP0]], -9
// CHECK: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
// CHECK-NOT: switch i32
// CHECK-NOT: br
// CHECK-NOT: label
// CHECK: ret i1 [[SWITCH_SELECTCMP]]
//
match input {
0b00010000 | 0b00001000 => true,
_ => false,
}
}
20 changes: 20 additions & 0 deletions tests/codegen/nonzero-type-not-zero-on-get.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ compile-flags: -O
//! Ensure that `.get()` on `std::num::NonZero*` types do not
//! check for zero equivalency.
//! Discovered in issue #49572.
#![crate_type = "lib"]

#[no_mangle]
pub fn foo(x: std::num::NonZeroU32) -> bool {
// CHECK-LABEL: @foo(
// CHECK: ret i1 true
x.get() != 0
}

#[no_mangle]
pub fn bar(x: std::num::NonZeroI64) -> bool {
// CHECK-LABEL: @bar(
// CHECK: ret i1 true
x.get() != 0
}
41 changes: 41 additions & 0 deletions tests/codegen/unreachable-branch-not-generated.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//@ compile-flags: -O
//! Ensure that matching on `x % 5` generates an unreachable
//! branch for values greater than 4.
//! Discovered in issue #93514.
#![crate_type = "lib"]

#[no_mangle]
pub unsafe fn parse0(x: u32) -> u32 {
// CHECK-LABEL: i32 @parse0(
// CHECK-SAME: i32 noundef [[X:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-NEXT: [[START:.*:]]
// CHECK-NEXT: [[_2:%.*]] = urem i32 [[X]], 5
// CHECK-NEXT: switch i32 [[_2]], label %[[DEFAULT_UNREACHABLE1:.*]] [
// CHECK-NEXT: i32 0, label %[[BB6:.*]]
// CHECK-NEXT: i32 1, label %[[BB5:.*]]
// CHECK-NEXT: i32 2, label %[[BB4:.*]]
// CHECK-NEXT: i32 3, label %[[BB3:.*]]
// CHECK-NEXT: i32 4, label %[[BB2:.*]]
// CHECK-NEXT: ]
// CHECK: [[DEFAULT_UNREACHABLE1]]:
// CHECK-NEXT: unreachable
// CHECK: ret i32
match x % 5 {
0 => f1(x),
1 => f2(x),
2 => f3(x),
3 => f4(x),
4 => f5(x),
_ => eliminate_me(),
}
}

extern "Rust" {
fn eliminate_me() -> u32;
fn f1(x: u32) -> u32;
fn f2(x: u32) -> u32;
fn f3(x: u32) -> u32;
fn f4(x: u32) -> u32;
fn f5(x: u32) -> u32;
}

0 comments on commit 816104f

Please sign in to comment.