Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit b96f962

Browse files
committed
Auto merge of rust-lang#138193 - FractalFir:ovf_checks, r=<try>
[Perf experiment] Make checked unsigned add not use intrinsics in debug mode **NOT MEANT FOR MERGING YET** This PR replaces unsigned checked addition LLVM intrinsic with simpler, inline implementations *in debug mode*. # Motivation According to the [LLVM performance tips]( https://llvm.org/docs/Frontend/PerformanceTips.html), arithmetics intrinsic (including overflow checks) should be avoided if possible, since the optimizer is not as good at reasoning about them: > Avoid using arithmetic intrinsics unless you are required by your source language specification to emit a particular code sequence. The optimizer is quite good at reasoning about general control flow and arithmetic, it is not anywhere near as strong at reasoning about the various intrinsics. If profitable for code generation purposes, the optimizer will likely form the intrinsics itself late in the optimization pipeline. It is very rarely profitable to emit these directly in the language frontend. This item explicitly includes the use of the overflow intrinsics. The goal of this PR is to check if using a simple, inline implementation of overflow checks is beneficial for compile times, compared to just using the intrinsic. From my research, in debug mode, the runtime performance of manual overflow checks is comparable to the performance of intrinsics. I will perform a perf run to see if: 1. This PR improves compiletimes. 2. This PR does not degrade debug runtime performance in a noticeable way. # Implementation The inline overflow checks are performed by comparing the sum of two numbers to the result of or-ing them together. The sum `a + b` is smaller than `a | b` if and only if an overflow occurs. This is used to detect overflows.
2 parents c53af1c + ffc4850 commit b96f962

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,13 +550,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
550550
Int(I32) => "llvm.sadd.with.overflow.i32",
551551
Int(I64) => "llvm.sadd.with.overflow.i64",
552552
Int(I128) => "llvm.sadd.with.overflow.i128",
553-
553+
Uint(_) if self.cx.sess().opts.optimize == OptLevel::No => {
554+
let sum = self.add(lhs, rhs);
555+
let ord = self.or(lhs, rhs);
556+
let cmp = self.icmp(IntPredicate::IntULT, sum, ord);
557+
return (sum, cmp);
558+
}
554559
Uint(U8) => "llvm.uadd.with.overflow.i8",
555560
Uint(U16) => "llvm.uadd.with.overflow.i16",
556561
Uint(U32) => "llvm.uadd.with.overflow.i32",
557562
Uint(U64) => "llvm.uadd.with.overflow.i64",
558563
Uint(U128) => "llvm.uadd.with.overflow.i128",
559-
560564
_ => unreachable!(),
561565
},
562566
OverflowOp::Sub => match new_kind {

0 commit comments

Comments
 (0)