[LVI] Support no constant range of cast value in getEdgeValueLocal. (#157614)
proof: https://alive2.llvm.org/ce/z/8emkHY
This commit is contained in:
parent
b44e6e01f7
commit
2701a220fa
@ -1493,6 +1493,24 @@ LazyValueInfoImpl::getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
|
||||
// br %Condition, label %then, label %else
|
||||
APInt ConditionVal(1, isTrueDest ? 1 : 0);
|
||||
Result = constantFoldUser(Usr, Condition, ConditionVal, DL);
|
||||
} else if (isa<TruncInst, ZExtInst, SExtInst>(Usr)) {
|
||||
ValueLatticeElement OpLatticeVal =
|
||||
*getValueFromCondition(Usr->getOperand(0), Condition,
|
||||
isTrueDest, /*UseBlockValue*/ false);
|
||||
|
||||
if (!OpLatticeVal.isConstantRange())
|
||||
return OpLatticeVal;
|
||||
|
||||
const unsigned ResultBitWidth =
|
||||
Usr->getType()->getScalarSizeInBits();
|
||||
if (auto *Trunc = dyn_cast<TruncInst>(Usr))
|
||||
return ValueLatticeElement::getRange(
|
||||
OpLatticeVal.getConstantRange().truncate(
|
||||
ResultBitWidth, Trunc->getNoWrapKind()));
|
||||
|
||||
return ValueLatticeElement::getRange(
|
||||
OpLatticeVal.getConstantRange().castOp(
|
||||
cast<CastInst>(Usr)->getOpcode(), ResultBitWidth));
|
||||
} else {
|
||||
// If one of Val's operand has an inferred value, we may be able to
|
||||
// infer the value of Val.
|
||||
|
||||
@ -1235,6 +1235,126 @@ define i1 @neg_icmp_eq_range_call() {
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i16 @return_range_for_edge_value_zext(i8 %a) {
|
||||
; CHECK-LABEL: define range(i16 0, 98) i16 @return_range_for_edge_value_zext(
|
||||
; CHECK-SAME: i8 [[A:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i16
|
||||
; CHECK-NEXT: br label %[[DISPATCH:.*]]
|
||||
; CHECK: [[DISPATCH]]:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A]], 98
|
||||
; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]
|
||||
; CHECK: [[TARGET]]:
|
||||
; CHECK-NEXT: ret i16 [[B]]
|
||||
;
|
||||
entry:
|
||||
%b = zext i8 %a to i16
|
||||
br label %dispatch
|
||||
|
||||
dispatch:
|
||||
%cmp = icmp ult i8 %a, 98
|
||||
br i1 %cmp, label %target, label %dispatch
|
||||
|
||||
target:
|
||||
ret i16 %b
|
||||
}
|
||||
|
||||
define i16 @return_range_for_edge_value_sext(i8 %a) {
|
||||
; CHECK-LABEL: define range(i16 -55, 0) i16 @return_range_for_edge_value_sext(
|
||||
; CHECK-SAME: i8 [[A:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[B:%.*]] = sext i8 [[A]] to i16
|
||||
; CHECK-NEXT: br label %[[DISPATCH:.*]]
|
||||
; CHECK: [[DISPATCH]]:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[A]], -56
|
||||
; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]
|
||||
; CHECK: [[TARGET]]:
|
||||
; CHECK-NEXT: ret i16 [[B]]
|
||||
;
|
||||
entry:
|
||||
%b = sext i8 %a to i16
|
||||
br label %dispatch
|
||||
|
||||
dispatch:
|
||||
%cmp = icmp ugt i8 %a, -56
|
||||
br i1 %cmp, label %target, label %dispatch
|
||||
|
||||
target:
|
||||
ret i16 %b
|
||||
}
|
||||
|
||||
define i8 @return_range_for_edge_value_trunc(i16 %a) {
|
||||
; CHECK-LABEL: define range(i8 0, 98) i8 @return_range_for_edge_value_trunc(
|
||||
; CHECK-SAME: i16 [[A:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[B:%.*]] = trunc i16 [[A]] to i8
|
||||
; CHECK-NEXT: br label %[[DISPATCH:.*]]
|
||||
; CHECK: [[DISPATCH]]:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[A]], 98
|
||||
; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]
|
||||
; CHECK: [[TARGET]]:
|
||||
; CHECK-NEXT: ret i8 [[B]]
|
||||
;
|
||||
entry:
|
||||
%b = trunc i16 %a to i8
|
||||
br label %dispatch
|
||||
|
||||
dispatch:
|
||||
%cmp = icmp ult i16 %a, 98
|
||||
br i1 %cmp, label %target, label %dispatch
|
||||
|
||||
target:
|
||||
ret i8 %b
|
||||
}
|
||||
|
||||
define i8 @neg_return_range_for_edge_value_trunc(i16 %a) {
|
||||
; CHECK-LABEL: define i8 @neg_return_range_for_edge_value_trunc(
|
||||
; CHECK-SAME: i16 [[A:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[B:%.*]] = trunc i16 [[A]] to i8
|
||||
; CHECK-NEXT: br label %[[DISPATCH:.*]]
|
||||
; CHECK: [[DISPATCH]]:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[A]], 200
|
||||
; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]
|
||||
; CHECK: [[TARGET]]:
|
||||
; CHECK-NEXT: ret i8 [[B]]
|
||||
;
|
||||
entry:
|
||||
%b = trunc i16 %a to i8
|
||||
br label %dispatch
|
||||
|
||||
dispatch:
|
||||
%cmp = icmp ugt i16 %a, 200
|
||||
br i1 %cmp, label %target, label %dispatch
|
||||
|
||||
target:
|
||||
ret i8 %b
|
||||
}
|
||||
|
||||
define i8 @return_range_for_edge_value_trunc_nuw(i16 %a) {
|
||||
; CHECK-LABEL: define range(i8 -55, 0) i8 @return_range_for_edge_value_trunc_nuw(
|
||||
; CHECK-SAME: i16 [[A:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[B:%.*]] = trunc nuw i16 [[A]] to i8
|
||||
; CHECK-NEXT: br label %[[DISPATCH:.*]]
|
||||
; CHECK: [[DISPATCH]]:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[A]], 200
|
||||
; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]
|
||||
; CHECK: [[TARGET]]:
|
||||
; CHECK-NEXT: ret i8 [[B]]
|
||||
;
|
||||
entry:
|
||||
%b = trunc nuw i16 %a to i8
|
||||
br label %dispatch
|
||||
|
||||
dispatch:
|
||||
%cmp = icmp ugt i16 %a, 200
|
||||
br i1 %cmp, label %target, label %dispatch
|
||||
|
||||
target:
|
||||
ret i8 %b
|
||||
}
|
||||
|
||||
declare i16 @llvm.ctlz.i16(i16, i1)
|
||||
declare i16 @llvm.cttz.i16(i16, i1)
|
||||
declare i16 @llvm.ctpop.i16(i16)
|
||||
|
||||
@ -18,8 +18,8 @@ if.end.i60: ; preds = %shadow_to_ptr.exit
|
||||
%spec.select.i = select i1 %cmp3.i, i32 -1, i32 %conv7.i, !dbg !17
|
||||
; Jump threading is going to fold the select in to the branch. Ensure debug
|
||||
; info is not lost, and is merged from the select and the branch.
|
||||
; CHECK-NOT: br i1 %cmp3.i, label %for.inc, label %ptr_to_shadow.exit
|
||||
; CHECK: br i1 %cmp3.i, label %for.inc, label %ptr_to_shadow.exit, !dbg [[DBG:![0-9]+]]
|
||||
; CHECK-NOT: br i1 %cmp3.i, label %for.inc, label %if.end22
|
||||
; CHECK: br i1 %cmp3.i, label %for.inc, label %if.end22, !dbg [[DBG:![0-9]+]]
|
||||
; CHECK: [[DBG]] = !DILocation(line: 9, column: 1, scope: !{{.*}})
|
||||
|
||||
br label %ptr_to_shadow.exit, !dbg !17
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user