mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[SCCP] Compute ranges for supported intrinsics
For intrinsics supported by ConstantRange, compute the result range based on the argument ranges. We do this independently of whether some or all of the input ranges are full, as we can often still constrain the result in some way. Differential Revision: https://reviews.llvm.org/D87183
This commit is contained in:
parent
558281ef53
commit
6a9be09c82
@ -1350,6 +1350,25 @@ void SCCPSolver::handleCallResult(CallBase &CB) {
|
||||
|
||||
return (void)mergeInValue(IV, &CB, CopyOfVal);
|
||||
}
|
||||
|
||||
if (ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
|
||||
// Compute result range for intrinsics supported by ConstantRange.
|
||||
// Do this even if we don't know a range for all operands, as we may
|
||||
// still know something about the result range, e.g. of abs(x).
|
||||
SmallVector<ConstantRange, 2> OpRanges;
|
||||
for (Value *Op : II->args()) {
|
||||
const ValueLatticeElement &State = getValueState(Op);
|
||||
if (State.isConstantRange())
|
||||
OpRanges.push_back(State.getConstantRange());
|
||||
else
|
||||
OpRanges.push_back(
|
||||
ConstantRange::getFull(Op->getType()->getScalarSizeInBits()));
|
||||
}
|
||||
|
||||
ConstantRange Result =
|
||||
ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges);
|
||||
return (void)mergeInValue(II, ValueLatticeElement::getRange(Result));
|
||||
}
|
||||
}
|
||||
|
||||
// The common case is that we aren't tracking the callee, either because we
|
||||
|
@ -12,10 +12,8 @@ define void @abs1(i8* %p) {
|
||||
; CHECK-LABEL: @abs1(
|
||||
; CHECK-NEXT: [[X:%.*]] = load i8, i8* [[P:%.*]], align 1, [[RNG0:!range !.*]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i8 [[ABS]], 0
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP1]])
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[ABS]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP2]])
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i8 [[ABS]], 1
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP3]])
|
||||
; CHECK-NEXT: [[CMP4:%.*]] = icmp slt i8 [[ABS]], 9
|
||||
@ -40,8 +38,7 @@ define void @abs1(i8* %p) {
|
||||
define void @abs2(i8 %x) {
|
||||
; CHECK-LABEL: @abs2(
|
||||
; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[ABS]], 0
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP]])
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%abs = call i8 @llvm.abs.i8(i8 %x, i1 true)
|
||||
@ -68,10 +65,8 @@ define void @umax1(i8* %p1, i8* %p2) {
|
||||
; CHECK-NEXT: [[X1:%.*]] = load i8, i8* [[P1:%.*]], align 1, [[RNG1:!range !.*]]
|
||||
; CHECK-NEXT: [[X2:%.*]] = load i8, i8* [[P2:%.*]], align 1, [[RNG2:!range !.*]]
|
||||
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[X1]], i8 [[X2]])
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i8 [[M]], 5
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP1]])
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 [[M]], 15
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP2]])
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: [[CMP3:%.*]] = icmp uge i8 [[M]], 6
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP3]])
|
||||
; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i8 [[M]], 14
|
||||
@ -95,8 +90,7 @@ define void @umax1(i8* %p1, i8* %p2) {
|
||||
define void @umax2(i8 %x) {
|
||||
; CHECK-LABEL: @umax2(
|
||||
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 10)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[M]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP]])
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%m = call i8 @llvm.umax.i8(i8 %x, i8 10)
|
||||
|
Loading…
Reference in New Issue
Block a user