From 4669c0d756ddfbd3df0ee1d5c7a4b1cdaabf5945 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 29 Nov 2024 22:51:46 -0800 Subject: Override `carrying_mul_add` in cg_llvm --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 31 ++++++++++++++++++++++++++++ compiler/rustc_codegen_llvm/src/lib.rs | 1 + 2 files changed, 32 insertions(+) (limited to 'compiler/rustc_codegen_llvm/src') 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 -- cgit 1.4.1-3-g733a5 From 62bb35ab5d99dc0b7d6cc77687b09e94ccd228c6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 29 Dec 2024 11:10:36 +0100 Subject: make -Csoft-float have an effect on all ARM targets --- compiler/rustc_codegen_llvm/src/back/write.rs | 2 +- compiler/rustc_session/src/session.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 45294ea35b1..ae5e818d86f 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -189,7 +189,7 @@ pub(crate) fn target_machine_factory( let reloc_model = to_llvm_relocation_model(sess.relocation_model()); let (opt_level, _) = to_llvm_opt_settings(optlvl); - let use_softfp = if sess.target.arch == "arm" && sess.target.abi == "eabihf" { + let use_softfp = if sess.target.arch == "arm" { sess.opts.cg.soft_float } else { // `validate_commandline_args_with_session_available` has already warned about this being diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 54bb4622963..60f1154dc6d 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1320,7 +1320,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } if sess.opts.cg.soft_float { - if sess.target.arch == "arm" && sess.target.abi == "eabihf" { + if sess.target.arch == "arm" { sess.dcx().emit_warn(errors::SoftFloatDeprecated); } else { // All `use_softfp` does is the equivalent of `-mfloat-abi` in GCC/clang, which only exists on ARM targets. -- cgit 1.4.1-3-g733a5