diff options
| author | bors <bors@rust-lang.org> | 2024-03-13 00:03:50 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-03-13 00:03:50 +0000 |
| commit | e61dcc7a0ac33ef054d76453307124233edcf545 (patch) | |
| tree | 73ec720f90a2c1636b5f37fde12af6c0f35c6230 | |
| parent | a165f1f65015b1bd4afd2ec50700aaacf2e0c485 (diff) | |
| parent | aa6cfb2669e51b3211017bde2faa6eddba22ecbe (diff) | |
| download | rust-e61dcc7a0ac33ef054d76453307124233edcf545.tar.gz rust-e61dcc7a0ac33ef054d76453307124233edcf545.zip | |
Auto merge of #122220 - saethlin:ppc-can-into-atomicptr, r=oli-obk
Only generate a ptrtoint in AtomicPtr codegen when absolutely necessary
This special case was added in this PR: https://github.com/rust-lang/rust/pull/77611 in response to this error message:
```
Intrinsic has incorrect argument type!
void ({}*)* `@llvm.ppc.cfence.p0sl_s`
in function rust_oom
LLVM ERROR: Broken function found, compilation aborted!
[RUSTC-TIMING] std test:false 20.161
error: could not compile `std`
```
But when I tried searching for more information about that intrinsic I found this: https://github.com/llvm/llvm-project/issues/55983 which is a report of someone hitting this same error and a fix was landed in LLVM, 2 years after the above Rust PR.
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/builder.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/common.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 50 |
3 files changed, 18 insertions, 42 deletions
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index ca2e2b57580..63e59ea13fc 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1132,9 +1132,15 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { &mut self, op: rustc_codegen_ssa::common::AtomicRmwBinOp, dst: &'ll Value, - src: &'ll Value, + mut src: &'ll Value, order: rustc_codegen_ssa::common::AtomicOrdering, ) -> &'ll Value { + // The only RMW operation that LLVM supports on pointers is compare-exchange. + if self.val_ty(src) == self.type_ptr() + && op != rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicXchg + { + src = self.ptrtoint(src, self.type_isize()); + } unsafe { llvm::LLVMBuildAtomicRMW( self.llbuilder, diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 641ac3eb808..44a2434238d 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -42,7 +42,7 @@ pub enum RealPredicate { RealPredicateTrue, } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq)] pub enum AtomicRmwBinOp { AtomicXchg, AtomicAdd, diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 82488829b6e..1d1826d9844 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -350,14 +350,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { let weak = instruction == "cxchgweak"; let dst = args[0].immediate(); - let mut cmp = args[1].immediate(); - let mut src = args[2].immediate(); - if ty.is_unsafe_ptr() { - // Some platforms do not support atomic operations on pointers, - // so we cast to integer first. - cmp = bx.ptrtoint(cmp, bx.type_isize()); - src = bx.ptrtoint(src, bx.type_isize()); - } + let cmp = args[1].immediate(); + let src = args[2].immediate(); let (val, success) = bx.atomic_cmpxchg( dst, cmp, @@ -385,26 +379,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = bx.layout_of(ty); let size = layout.size; let source = args[0].immediate(); - if ty.is_unsafe_ptr() { - // Some platforms do not support atomic operations on pointers, - // so we cast to integer first... - let llty = bx.type_isize(); - let result = bx.atomic_load( - llty, - source, - parse_ordering(bx, ordering), - size, - ); - // ... and then cast the result back to a pointer - bx.inttoptr(result, bx.backend_type(layout)) - } else { - bx.atomic_load( - bx.backend_type(layout), - source, - parse_ordering(bx, ordering), - size, - ) - } + bx.atomic_load( + bx.backend_type(layout), + source, + parse_ordering(bx, ordering), + size, + ) } else { invalid_monomorphization(ty); return Ok(()); @@ -415,13 +395,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = fn_args.type_at(0); if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { let size = bx.layout_of(ty).size; - let mut val = args[1].immediate(); + let val = args[1].immediate(); let ptr = args[0].immediate(); - if ty.is_unsafe_ptr() { - // Some platforms do not support atomic operations on pointers, - // so we cast to integer first. - val = bx.ptrtoint(val, bx.type_isize()); - } bx.atomic_store(val, ptr, parse_ordering(bx, ordering), size); } else { invalid_monomorphization(ty); @@ -465,12 +440,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = fn_args.type_at(0); if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { let ptr = args[0].immediate(); - let mut val = args[1].immediate(); - if ty.is_unsafe_ptr() { - // Some platforms do not support atomic operations on pointers, - // so we cast to integer first. - val = bx.ptrtoint(val, bx.type_isize()); - } + let val = args[1].immediate(); bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering)) } else { invalid_monomorphization(ty); |
