diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-08-07 05:29:12 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-07 05:29:12 +0200 |
| commit | cbe25226525ac010295c666c05fef7a81e99984c (patch) | |
| tree | 6688fd8ce90bf73370c71d077d76e32d502766ec /compiler/rustc_codegen_llvm/src | |
| parent | f5df519fe7da5fc62656e9a4c46ed7f6b9742def (diff) | |
| parent | 75277a6606e8c7443ccd3fd1a2562c166fed7298 (diff) | |
| download | rust-cbe25226525ac010295c666c05fef7a81e99984c.tar.gz rust-cbe25226525ac010295c666c05fef7a81e99984c.zip | |
Rollup merge of #114382 - scottmcm:compare-bytes-intrinsic, r=cjgillot
Add a new `compare_bytes` intrinsic instead of calling `memcmp` directly As discussed in #113435, this lets the backends be the place that can have the "don't call the function if n == 0" logic, if it's needed for the target. (I didn't actually *add* those checks, though, since as I understood it we didn't actually need them on known targets?) Doing this also let me make it `const` (unstable), which I don't think `extern "C" fn memcmp` can be. cc `@RalfJung` `@Amanieu`
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/context.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/intrinsic.rs | 10 |
2 files changed, 12 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 3577fb2d951..2d23be6cd52 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -891,7 +891,8 @@ impl<'ll> CodegenCx<'ll, '_> { ifn!("llvm.prefetch", fn(ptr, t_i32, t_i32, t_i32) -> void); // This isn't an "LLVM intrinsic", but LLVM's optimization passes - // recognize it like one and we assume it exists in `core::slice::cmp` + // recognize it like one (including turning it into `bcmp` sometimes) + // and we use it to implement intrinsics like `raw_eq` and `compare_bytes` match self.sess().target.arch.as_ref() { "avr" | "msp430" => ifn!("memcmp", fn(ptr, ptr, t_isize) -> t_i16), _ => ifn!("memcmp", fn(ptr, ptr, t_isize) -> t_i32), diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 6f1e4c5178a..a9b06030e70 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -329,6 +329,16 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { } } + sym::compare_bytes => { + // Here we assume that the `memcmp` provided by the target is a NOP for size 0. + let cmp = self.call_intrinsic( + "memcmp", + &[args[0].immediate(), args[1].immediate(), args[2].immediate()], + ); + // Some targets have `memcmp` returning `i16`, but the intrinsic is always `i32`. + self.sext(cmp, self.type_ix(32)) + } + sym::black_box => { args[0].val.store(self, result); let result_val_span = [result.llval]; |
