
Fix overflow check Make MIRI choose the path randomly and rename the intrinsic Add back test Add miri test and make it operate on `ptr` Define `llvm.is.constant` for primitives Update MIRI comment and fix test in stage2 Add const eval test Clarify that both branches must have the same side effects guaranteed non guarantee use immediate type instead Co-Authored-By: Ralf Jung <post@ralfj.de>
68 lines
2.4 KiB
Rust
68 lines
2.4 KiB
Rust
// #[cfg(bootstrap)]
|
|
// ignore-stage1
|
|
// compile-flags: --crate-type=lib -Zmerge-functions=disabled
|
|
|
|
// CHECK-LABEL: @a(
|
|
#[no_mangle]
|
|
pub fn a(exp: u32) -> u64 {
|
|
// CHECK: %[[R:.+]] = and i32 %exp, 63
|
|
// CHECK: %[[R:.+]] = zext i32 %[[R:.+]] to i64
|
|
// CHECK: %[[R:.+]] = shl nuw i64 %[[R:.+]].i, %[[R:.+]]
|
|
// CHECK: ret i64 %[[R:.+]]
|
|
2u64.pow(exp)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub fn b(exp: u32) -> i64 {
|
|
// CHECK: %[[R:.+]] = and i32 %exp, 63
|
|
// CHECK: %[[R:.+]] = zext i32 %[[R:.+]] to i64
|
|
// CHECK: %[[R:.+]] = shl nuw i64 %[[R:.+]].i, %[[R:.+]]
|
|
// CHECK: ret i64 %[[R:.+]]
|
|
2i64.pow(exp)
|
|
}
|
|
|
|
// CHECK-LABEL: @c(
|
|
#[no_mangle]
|
|
pub fn c(exp: u32) -> u32 {
|
|
// CHECK: %[[R:.+]].0.i = shl i32 %exp, 1
|
|
// CHECK: %[[R:.+]].1.i = icmp sgt i32 %exp, -1
|
|
// CHECK: %[[R:.+]].i = icmp ult i32 %[[R:.+]].0.i, 32
|
|
// CHECK: %fine.i = and i1 %[[R:.+]].1.i, %[[R:.+]].i
|
|
// CHECK: %0 = and i32 %[[R:.+]].0.i, 30
|
|
// CHECK: %[[R:.+]].i = zext i1 %fine.i to i32
|
|
// CHECK: %[[R:.+]] = shl nuw nsw i32 %[[R:.+]].i, %0
|
|
// CHECK: ret i32 %[[R:.+]]
|
|
4u32.pow(exp)
|
|
}
|
|
|
|
// CHECK-LABEL: @d(
|
|
#[no_mangle]
|
|
pub fn d(exp: u32) -> u32 {
|
|
// CHECK: tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %exp, i32 5)
|
|
// CHECK: %[[R:.+]].0.i = extractvalue { i32, i1 } %[[R:.+]], 0
|
|
// CHECK: %[[R:.+]].1.i = extractvalue { i32, i1 } %[[R:.+]], 1
|
|
// CHECK: %[[R:.+]].i = xor i1 %[[R:.+]].1.i, true
|
|
// CHECK: %[[R:.+]].i = icmp ult i32 %[[R:.+]].0.i, 32
|
|
// CHECK: %fine.i = and i1 %[[R:.+]].i, %[[R:.+]].i
|
|
// CHECK: %[[R:.+]] = and i32 %[[R:.+]].0.i, 31
|
|
// CHECK: %[[R:.+]].i = zext i1 %fine.i to i32
|
|
// CHECK: %[[R:.+]] = shl nuw i32 %[[R:.+]].i, %1
|
|
// CHECK: ret i32 %[[R:.+]]
|
|
32u32.pow(exp)
|
|
}
|
|
|
|
// CHECK-LABEL: @e(
|
|
#[no_mangle]
|
|
pub fn e(exp: u32) -> i32 {
|
|
// CHECK: tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %exp, i32 5)
|
|
// CHECK: %[[R:.+]].0.i = extractvalue { i32, i1 } %[[R:.+]], 0
|
|
// CHECK: %[[R:.+]].i = icmp ult i32 %[[R:.+]].0.i, 32
|
|
// CHECK: %[[R:.+]].1.i = extractvalue { i32, i1 } %[[R:.+]], 1
|
|
// CHECK: %[[R:.+]].i = xor i1 %[[R:.+]].1.i, true
|
|
// CHECK: %fine.i = and i1 %[[R:.+]].i, %[[R:.+]].i
|
|
// CHECK: %[[R:.+]].i = zext i1 %fine.i to i32
|
|
// CHECK: %[[R:.+]] = and i32 %[[R:.+]].0.i, 31
|
|
// CHECK: %[[R:.+]] = shl nuw i32 %[[R:.+]].i, %1
|
|
// CHECK: ret i32 %[[R:.+]]
|
|
32i32.pow(exp)
|
|
}
|