diff options
| author | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-02-02 19:23:44 -0800 |
|---|---|---|
| committer | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-02-02 21:04:10 -0800 |
| commit | f46e6be1908c7ed729655c8f601548f732ef49f4 (patch) | |
| tree | 5d070451c3664dedadbb74a0f3b0cbcafdaef473 | |
| parent | 5e6ae8bb5c884deea85c6f18cfba79fe48ccafa0 (diff) | |
| download | rust-f46e6be1908c7ed729655c8f601548f732ef49f4.tar.gz rust-f46e6be1908c7ed729655c8f601548f732ef49f4.zip | |
Handle the case where the `or disjoint` folds immediately to a constant
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/builder.rs | 8 | ||||
| -rw-r--r-- | tests/codegen/intrinsics/disjoint_bitor.rs | 12 |
2 files changed, 18 insertions, 2 deletions
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 6e1eec4f0fc..264d43c6d46 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -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 } } diff --git a/tests/codegen/intrinsics/disjoint_bitor.rs b/tests/codegen/intrinsics/disjoint_bitor.rs index be9954507b3..fc45439ee0b 100644 --- a/tests/codegen/intrinsics/disjoint_bitor.rs +++ b/tests/codegen/intrinsics/disjoint_bitor.rs @@ -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)] @@ -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) +} |
