mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[ValueTracking] Handle increasing mul recurrence in isKnownNonZero()
Differential Revision: https://reviews.llvm.org/D99069
This commit is contained in:
parent
3b0888e5fb
commit
af9f082c95
@ -2450,21 +2450,19 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
|
||||
else if (const PHINode *PN = dyn_cast<PHINode>(V)) {
|
||||
// Try and detect a recurrence that monotonically increases from a
|
||||
// starting value, as these are common as induction variables.
|
||||
if (PN->getNumIncomingValues() == 2) {
|
||||
Value *Start = PN->getIncomingValue(0);
|
||||
Value *Induction = PN->getIncomingValue(1);
|
||||
if (isa<ConstantInt>(Induction) && !isa<ConstantInt>(Start))
|
||||
std::swap(Start, Induction);
|
||||
if (ConstantInt *C = dyn_cast<ConstantInt>(Start)) {
|
||||
if (!C->isZero() && !C->isNegative()) {
|
||||
ConstantInt *X;
|
||||
if (Q.IIQ.UseInstrInfo &&
|
||||
(match(Induction, m_NSWAdd(m_Specific(PN), m_ConstantInt(X))) ||
|
||||
match(Induction, m_NUWAdd(m_Specific(PN), m_ConstantInt(X)))) &&
|
||||
!X->isNegative())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
BinaryOperator *BO = nullptr;
|
||||
Value *Start = nullptr, *Step = nullptr;
|
||||
const APInt *StartC, *StepC;
|
||||
if (Q.IIQ.UseInstrInfo && matchSimpleRecurrence(PN, BO, Start, Step) &&
|
||||
match(Start, m_APInt(StartC)) && match(Step, m_APInt(StepC))) {
|
||||
if (BO->getOpcode() == Instruction::Add &&
|
||||
(BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap()) &&
|
||||
StartC->isStrictlyPositive() && !StepC->isNegative())
|
||||
return true;
|
||||
if (BO->getOpcode() == Instruction::Mul &&
|
||||
(BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap()) &&
|
||||
!StartC->isNullValue() && StepC->isStrictlyPositive())
|
||||
return true;
|
||||
}
|
||||
// Check if all incoming values are non-zero using recursion.
|
||||
Query RecQ = Q;
|
||||
|
@ -77,3 +77,204 @@ exit:
|
||||
%cmp = icmp eq i8 %add, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @test4(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
; CHECK-LABEL: @test4(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[NEXT]] = add nuw i8 [[A]], 1
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[ADD:%.*]] = or i8 [[A]], [[R:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[ADD]], 0
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ 0, %entry ], [ %next, %loop ]
|
||||
%next = add nuw i8 %A, 1
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%add = or i8 %A, %r
|
||||
%cmp = icmp eq i8 %add, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @test5(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
; CHECK-LABEL: @test5(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i8 [ -2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[NEXT]] = add nuw i8 [[A]], 1
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[ADD:%.*]] = or i8 [[A]], [[R:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[ADD]], 0
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ -2, %entry ], [ %next, %loop ]
|
||||
%next = add nuw i8 %A, 1
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%add = or i8 %A, %r
|
||||
%cmp = icmp eq i8 %add, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @test6(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
; CHECK-LABEL: @test6(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[NEXT]] = mul nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ 2, %entry ], [ %next, %loop ]
|
||||
%next = mul nsw i8 %A, 2
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%cmp = icmp eq i8 %A, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @test7(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
; CHECK-LABEL: @test7(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[NEXT]] = mul i8 [[A]], 2
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 0
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ 2, %entry ], [ %next, %loop ]
|
||||
%next = mul i8 %A, 2
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%cmp = icmp eq i8 %A, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @test8(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
; CHECK-LABEL: @test8(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[NEXT]] = mul nuw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ 2, %entry ], [ %next, %loop ]
|
||||
%next = mul nuw i8 %A, 2
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%cmp = icmp eq i8 %A, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @test9(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
; CHECK-LABEL: @test9(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[NEXT]] = mul nuw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 0
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ 0, %entry ], [ %next, %loop ]
|
||||
%next = mul nuw i8 %A, 2
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%cmp = icmp eq i8 %A, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @test10(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
; CHECK-LABEL: @test10(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[NEXT]] = mul nuw i8 [[A]], -2
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 0
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ 2, %entry ], [ %next, %loop ]
|
||||
%next = mul nuw i8 %A, -2
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%cmp = icmp eq i8 %A, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @test11(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
; CHECK-LABEL: @test11(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i8 [ -2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[NEXT]] = mul nuw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ -2, %entry ], [ %next, %loop ]
|
||||
%next = mul nuw i8 %A, 2
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%cmp = icmp eq i8 %A, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user