Skip to content

Commit f46e6be

Browse files
committed
Handle the case where the or disjoint folds immediately to a constant
1 parent 5e6ae8b commit f46e6be

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
424424
fn or_disjoint(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
425425
unsafe {
426426
let or = llvm::LLVMBuildOr(self.llbuilder, a, b, UNNAMED);
427-
llvm::LLVMSetIsDisjoint(or, True);
427+
428+
// If a and b are both values, then `or` is a value, rather than
429+
// an instruction, so we need to check before setting the flag.
430+
// (See also `LLVMBuildNUWNeg` which also needs a check.)
431+
if llvm::LLVMIsAInstruction(or).is_some() {
432+
llvm::LLVMSetIsDisjoint(or, True);
433+
}
428434
or
429435
}
430436
}

tests/codegen/intrinsics/disjoint_bitor.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@ compile-flags: -C no-prepopulate-passes
1+
//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0
22

33
#![crate_type = "lib"]
44
#![feature(core_intrinsics)]
@@ -18,3 +18,13 @@ pub unsafe fn disjoint_bitor_unsigned(x: u64, y: u64) -> u64 {
1818
// CHECK: or disjoint i64 %x, %y
1919
disjoint_bitor(x, y)
2020
}
21+
22+
// CHECK-LABEL: @disjoint_bitor_literal
23+
#[no_mangle]
24+
pub unsafe fn disjoint_bitor_literal() -> u8 {
25+
// This is a separate check because even without any passes,
26+
// LLVM will fold so it's not an instruction, which can assert in LLVM.
27+
28+
// CHECK: store i8 3
29+
disjoint_bitor(1, 2)
30+
}

0 commit comments

Comments
 (0)