Skip to content

Commit 4ee1602

Browse files
committed
Override disjoint_or in the LLVM backend
1 parent f230253 commit 4ee1602

File tree

6 files changed

+54
-0
lines changed

6 files changed

+54
-0
lines changed

Diff for: compiler/rustc_codegen_llvm/src/builder.rs

+8
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
421421
unchecked_umul(x, y) => LLVMBuildNUWMul,
422422
}
423423

424+
fn or_disjoint(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
425+
unsafe {
426+
let or = llvm::LLVMBuildOr(self.llbuilder, a, b, UNNAMED);
427+
llvm::LLVMSetIsDisjoint(or, True);
428+
or
429+
}
430+
}
431+
424432
set_math_builder_methods! {
425433
fadd_fast(x, y) => (LLVMBuildFAdd, LLVMRustSetFastMath),
426434
fsub_fast(x, y) => (LLVMBuildFSub, LLVMRustSetFastMath),

Diff for: compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,9 @@ unsafe extern "C" {
13801380
pub fn LLVMBuildFNeg<'a>(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value;
13811381
pub fn LLVMBuildNot<'a>(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value;
13821382

1383+
// Extra flags on arithmetic
1384+
pub fn LLVMSetIsDisjoint(Instr: &Value, IsDisjoint: Bool);
1385+
13831386
// Memory
13841387
pub fn LLVMBuildAlloca<'a>(B: &Builder<'a>, Ty: &'a Type, Name: *const c_char) -> &'a Value;
13851388
pub fn LLVMBuildArrayAlloca<'a>(

Diff for: compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

+5
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
225225
args[1].val.unaligned_volatile_store(bx, dst);
226226
return Ok(());
227227
}
228+
sym::disjoint_bitor => {
229+
let a = args[0].immediate();
230+
let b = args[1].immediate();
231+
bx.or_disjoint(a, b)
232+
}
228233
sym::exact_div => {
229234
let ty = arg_tys[0];
230235
match int_type_width_signed(ty, bx.tcx()) {

Diff for: compiler/rustc_codegen_ssa/src/traits/builder.rs

+5
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ pub trait BuilderMethods<'a, 'tcx>:
167167
fn unchecked_umul(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
168168
fn and(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
169169
fn or(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
170+
/// Defaults to [`Self::or`], but guarantees `(lhs & rhs) == 0` so some backends
171+
/// can emit something more helpful for optimizations.
172+
fn or_disjoint(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value {
173+
self.or(lhs, rhs)
174+
}
170175
fn xor(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
171176
fn neg(&mut self, v: Self::Value) -> Self::Value;
172177
fn fneg(&mut self, v: Self::Value) -> Self::Value;

Diff for: tests/codegen/bigint-helpers.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ compile-flags: -C opt-level=3
2+
3+
#![crate_type = "lib"]
4+
#![feature(bigint_helper_methods)]
5+
6+
// CHECK-LABEL: @u32_carrying_add
7+
#[no_mangle]
8+
pub fn u32_carrying_add(a: u32, b: u32, c: bool) -> (u32, bool) {
9+
// CHECK: @llvm.uadd.with.overflow.i32
10+
// CHECK: @llvm.uadd.with.overflow.i32
11+
// CHECK: or disjoint i1
12+
u32::carrying_add(a, b, c)
13+
}

Diff for: tests/codegen/intrinsics/disjoint_bitor.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//@ compile-flags: -C no-prepopulate-passes
2+
3+
#![crate_type = "lib"]
4+
#![feature(core_intrinsics)]
5+
6+
use std::intrinsics::disjoint_bitor;
7+
8+
// CHECK-LABEL: @disjoint_bitor_signed
9+
#[no_mangle]
10+
pub unsafe fn disjoint_bitor_signed(x: i32, y: i32) -> i32 {
11+
// CHECK: or disjoint i32 %x, %y
12+
disjoint_bitor(x, y)
13+
}
14+
15+
// CHECK-LABEL: @disjoint_bitor_unsigned
16+
#[no_mangle]
17+
pub unsafe fn disjoint_bitor_unsigned(x: u64, y: u64) -> u64 {
18+
// CHECK: or disjoint i64 %x, %y
19+
disjoint_bitor(x, y)
20+
}

0 commit comments

Comments
 (0)