diff options
| author | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-01-16 20:13:48 -0800 |
|---|---|---|
| committer | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-01-17 20:39:38 -0800 |
| commit | 6fe82006a4edf2d244f436aa7d14d985d0b1f39a (patch) | |
| tree | 31beb848a1193afd3386e88a04b1e5faeb2b3800 /compiler/rustc_codegen_ssa/src/traits | |
| parent | 76a030a6c2dab11760cb08d746fa515e4bce5d39 (diff) | |
Update our range `assume`s to the format that LLVM prefers
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/traits')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/builder.rs | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 3ee13b19f66..bbf87a59942 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -217,6 +217,27 @@ pub trait BuilderMethods<'a, 'tcx>: dest: PlaceRef<'tcx, Self::Value>, ); + /// Emits an `assume` that the integer value `imm` of type `ty` is contained in `range`. + /// + /// This *always* emits the assumption, so you probably want to check the + /// optimization level and `Scalar::is_always_valid` before calling it. + fn assume_integer_range(&mut self, imm: Self::Value, ty: Self::Type, range: WrappingRange) { + let WrappingRange { start, end } = range; + + // Perhaps one day we'll be able to use assume operand bundles for this, + // but for now this encoding with a single icmp+assume is best per + // <https://github.com/llvm/llvm-project/issues/123278#issuecomment-2597440158> + let shifted = if start == 0 { + imm + } else { + let low = self.const_uint_big(ty, start); + self.sub(imm, low) + }; + let width = self.const_uint_big(ty, u128::wrapping_sub(end, start)); + let cmp = self.icmp(IntPredicate::IntULE, shifted, width); + self.assume(cmp); + } + fn range_metadata(&mut self, load: Self::Value, range: WrappingRange); fn nonnull_metadata(&mut self, load: Self::Value); |
