diff options
| author | bors <bors@rust-lang.org> | 2024-12-27 19:30:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-12-27 19:30:32 +0000 |
| commit | dd84b7d5eec3c20d7fcd13e6450af029d3cece9d (patch) | |
| tree | b035f3b5ec4c5f45adcc258c664e2ed6a0b5e54e /compiler/rustc_codegen_llvm/src | |
| parent | e5f0d6ffbda2d23ca6729c3f93a8f54d86f920d5 (diff) | |
| parent | 6385e65d16f335777b45f4116a0d23eebff03b86 (diff) | |
| download | rust-dd84b7d5eec3c20d7fcd13e6450af029d3cece9d.tar.gz rust-dd84b7d5eec3c20d7fcd13e6450af029d3cece9d.zip | |
Auto merge of #134830 - matthiaskrgr:rollup-7hdjojz, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #133663 (Add a compiler intrinsic to back `bigint_helper_methods`) - #134798 (Make `ty::Error` implement all auto traits) - #134808 (compiletest: Remove empty 'expected' files when blessing) - #134809 (Add `--no-capture`/`--nocapture` as bootstrap arguments) - #134826 (Add spastorino to users_on_vacation) - #134828 (Add clubby789 back to bootstrap review rotation) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/intrinsic.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/lib.rs | 1 |
2 files changed, 32 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index c38c5d4c644..cabcfc9b42b 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -340,6 +340,37 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { self.const_i32(cache_type), ]) } + sym::carrying_mul_add => { + let (size, signed) = fn_args.type_at(0).int_size_and_signed(self.tcx); + + let wide_llty = self.type_ix(size.bits() * 2); + let args = args.as_array().unwrap(); + let [a, b, c, d] = args.map(|a| self.intcast(a.immediate(), wide_llty, signed)); + + let wide = if signed { + let prod = self.unchecked_smul(a, b); + let acc = self.unchecked_sadd(prod, c); + self.unchecked_sadd(acc, d) + } else { + let prod = self.unchecked_umul(a, b); + let acc = self.unchecked_uadd(prod, c); + self.unchecked_uadd(acc, d) + }; + + let narrow_llty = self.type_ix(size.bits()); + let low = self.trunc(wide, narrow_llty); + let bits_const = self.const_uint(wide_llty, size.bits()); + // No need for ashr when signed; LLVM changes it to lshr anyway. + let high = self.lshr(wide, bits_const); + // FIXME: could be `trunc nuw`, even for signed. + let high = self.trunc(high, narrow_llty); + + let pair_llty = self.type_struct(&[narrow_llty, narrow_llty], false); + let pair = self.const_poison(pair_llty); + let pair = self.insert_value(pair, low, 0); + let pair = self.insert_value(pair, high, 1); + pair + } sym::ctlz | sym::ctlz_nonzero | sym::cttz diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 0de0c6a7a89..dca7738daf7 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -17,6 +17,7 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![feature(slice_as_array)] #![feature(try_blocks)] #![warn(unreachable_pub)] // tidy-alphabetical-end |
