mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-14 04:56:49 +00:00
Override disjoint_or
in the LLVM backend
This commit is contained in:
parent
f23025305f
commit
4ee1602eab
@ -421,6 +421,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
unchecked_umul(x, y) => LLVMBuildNUWMul,
|
||||
}
|
||||
|
||||
fn or_disjoint(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
|
||||
unsafe {
|
||||
let or = llvm::LLVMBuildOr(self.llbuilder, a, b, UNNAMED);
|
||||
llvm::LLVMSetIsDisjoint(or, True);
|
||||
or
|
||||
}
|
||||
}
|
||||
|
||||
set_math_builder_methods! {
|
||||
fadd_fast(x, y) => (LLVMBuildFAdd, LLVMRustSetFastMath),
|
||||
fsub_fast(x, y) => (LLVMBuildFSub, LLVMRustSetFastMath),
|
||||
|
@ -1380,6 +1380,9 @@ unsafe extern "C" {
|
||||
pub fn LLVMBuildFNeg<'a>(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value;
|
||||
pub fn LLVMBuildNot<'a>(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value;
|
||||
|
||||
// Extra flags on arithmetic
|
||||
pub fn LLVMSetIsDisjoint(Instr: &Value, IsDisjoint: Bool);
|
||||
|
||||
// Memory
|
||||
pub fn LLVMBuildAlloca<'a>(B: &Builder<'a>, Ty: &'a Type, Name: *const c_char) -> &'a Value;
|
||||
pub fn LLVMBuildArrayAlloca<'a>(
|
||||
|
@ -225,6 +225,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
args[1].val.unaligned_volatile_store(bx, dst);
|
||||
return Ok(());
|
||||
}
|
||||
sym::disjoint_bitor => {
|
||||
let a = args[0].immediate();
|
||||
let b = args[1].immediate();
|
||||
bx.or_disjoint(a, b)
|
||||
}
|
||||
sym::exact_div => {
|
||||
let ty = arg_tys[0];
|
||||
match int_type_width_signed(ty, bx.tcx()) {
|
||||
|
@ -167,6 +167,11 @@ pub trait BuilderMethods<'a, 'tcx>:
|
||||
fn unchecked_umul(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn and(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn or(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
/// Defaults to [`Self::or`], but guarantees `(lhs & rhs) == 0` so some backends
|
||||
/// can emit something more helpful for optimizations.
|
||||
fn or_disjoint(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value {
|
||||
self.or(lhs, rhs)
|
||||
}
|
||||
fn xor(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn neg(&mut self, v: Self::Value) -> Self::Value;
|
||||
fn fneg(&mut self, v: Self::Value) -> Self::Value;
|
||||
|
13
tests/codegen/bigint-helpers.rs
Normal file
13
tests/codegen/bigint-helpers.rs
Normal file
@ -0,0 +1,13 @@
|
||||
//@ compile-flags: -C opt-level=3
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(bigint_helper_methods)]
|
||||
|
||||
// CHECK-LABEL: @u32_carrying_add
|
||||
#[no_mangle]
|
||||
pub fn u32_carrying_add(a: u32, b: u32, c: bool) -> (u32, bool) {
|
||||
// CHECK: @llvm.uadd.with.overflow.i32
|
||||
// CHECK: @llvm.uadd.with.overflow.i32
|
||||
// CHECK: or disjoint i1
|
||||
u32::carrying_add(a, b, c)
|
||||
}
|
20
tests/codegen/intrinsics/disjoint_bitor.rs
Normal file
20
tests/codegen/intrinsics/disjoint_bitor.rs
Normal file
@ -0,0 +1,20 @@
|
||||
//@ compile-flags: -C no-prepopulate-passes
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::disjoint_bitor;
|
||||
|
||||
// CHECK-LABEL: @disjoint_bitor_signed
|
||||
#[no_mangle]
|
||||
pub unsafe fn disjoint_bitor_signed(x: i32, y: i32) -> i32 {
|
||||
// CHECK: or disjoint i32 %x, %y
|
||||
disjoint_bitor(x, y)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @disjoint_bitor_unsigned
|
||||
#[no_mangle]
|
||||
pub unsafe fn disjoint_bitor_unsigned(x: u64, y: u64) -> u64 {
|
||||
// CHECK: or disjoint i64 %x, %y
|
||||
disjoint_bitor(x, y)
|
||||
}
|
Loading…
Reference in New Issue
Block a user