Skip to content

Commit 4c17eaa

Browse files
committed
Auto merge of rust-lang#122728 - DianQK:range_metadata, r=<try>
[WIP] Use assume rather than range metadata Fixes rust-lang#122726. Currently, range can only be used in load, call and invoke instructions. Due to SROA being run before other passes, even in the simplest IR, LLVM cannot infer that `%i1` is 0. ```llvm define noundef i32 `@src(i32` noundef %arg) { %i = alloca i32, align 4 store i32 %arg, ptr %i, align 4 %i1 = load i32, ptr %i, align 4, !range !0 ret i32 %i1 } ``` https://alive2.llvm.org/ce/z/MjsH9b r? `@ghost`
2 parents f296c16 + f50d551 commit 4c17eaa

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::abi::FnAbiLlvmExt;
22
use crate::attributes;
33
use crate::common::Funclet;
44
use crate::context::CodegenCx;
5-
use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True};
5+
use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, LLVMIsALoadInst, True};
66
use crate::llvm_util;
77
use crate::type_::Type;
88
use crate::type_of::LayoutLlvmExt;
@@ -662,12 +662,38 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
662662
// optimization.
663663
return;
664664
}
665+
let abi::WrappingRange { start, end } = range;
666+
let llty = self.cx.val_ty(load);
667+
if unsafe { LLVMIsALoadInst(load) }.is_some() {
668+
if start <= end {
669+
if start > 0 {
670+
let low = self.cx.const_uint_big(llty, start);
671+
let cmp = self.icmp(IntPredicate::IntUGE, load, low);
672+
self.assume(cmp);
673+
}
674+
let type_max = Size::from_bits(self.cx.int_width(llty)).unsigned_int_max();
675+
if end < type_max {
676+
let high = self.cx.const_uint_big(llty, end);
677+
let cmp = self.icmp(IntPredicate::IntULE, load, high);
678+
self.assume(cmp);
679+
}
680+
} else {
681+
let low = self.cx.const_uint_big(llty, start);
682+
let cmp_low = self.icmp(IntPredicate::IntUGE, load, low);
683+
684+
let high = self.cx.const_uint_big(llty, end);
685+
let cmp_high = self.icmp(IntPredicate::IntULE, load, high);
686+
687+
let or = self.or(cmp_low, cmp_high);
688+
self.assume(or);
689+
}
690+
return;
691+
}
665692

666693
unsafe {
667-
let llty = self.cx.val_ty(load);
668694
let v = [
669-
self.cx.const_uint_big(llty, range.start),
670-
self.cx.const_uint_big(llty, range.end.wrapping_add(1)),
695+
self.cx.const_uint_big(llty, start),
696+
self.cx.const_uint_big(llty, end.wrapping_add(1)),
671697
];
672698

673699
llvm::LLVMSetMetadata(

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,7 @@ extern "C" {
10171017

10181018
// Operations on instructions
10191019
pub fn LLVMIsAInstruction(Val: &Value) -> Option<&Value>;
1020+
pub fn LLVMIsALoadInst(Val: &Value) -> Option<&Value>;
10201021
pub fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock;
10211022

10221023
// Operations on call sites

0 commit comments

Comments
 (0)