Skip to content

Commit

Permalink
Handle the case where the or disjoint folds immediately to a constant
Browse files Browse the repository at this point in the history
  • Loading branch information
scottmcm committed Feb 3, 2025
1 parent 5e6ae8b commit f46e6be
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
8 changes: 7 additions & 1 deletion compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
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);

// If a and b are both values, then `or` is a value, rather than
// an instruction, so we need to check before setting the flag.
// (See also `LLVMBuildNUWNeg` which also needs a check.)
if llvm::LLVMIsAInstruction(or).is_some() {
llvm::LLVMSetIsDisjoint(or, True);
}
or
}
}
Expand Down
12 changes: 11 additions & 1 deletion tests/codegen/intrinsics/disjoint_bitor.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@ compile-flags: -C no-prepopulate-passes
//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0

#![crate_type = "lib"]
#![feature(core_intrinsics)]
Expand All @@ -18,3 +18,13 @@ pub unsafe fn disjoint_bitor_unsigned(x: u64, y: u64) -> u64 {
// CHECK: or disjoint i64 %x, %y
disjoint_bitor(x, y)
}

// CHECK-LABEL: @disjoint_bitor_literal
#[no_mangle]
pub unsafe fn disjoint_bitor_literal() -> u8 {
// This is a separate check because even without any passes,
// LLVM will fold so it's not an instruction, which can assert in LLVM.

// CHECK: store i8 3
disjoint_bitor(1, 2)
}

0 comments on commit f46e6be

Please sign in to comment.