Skip to content

Commit fef6613

Browse files
authored
ValueTracking: simplify udiv/urem recurrences (llvm#108973)
A urem recurrence has the property that the result can never exceed the start value. A udiv recurrence has the property that the result can never exceed either the start value or the numerator, whichever is greater. Implement a simplification based on these properties.
1 parent abe0cd4 commit fef6613

File tree

2 files changed

+21
-15
lines changed

2 files changed

+21
-15
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,16 +1426,23 @@ static void computeKnownBitsFromOperator(const Operator *I,
14261426
// this is sufficient to catch some interesting cases.
14271427
unsigned Opcode = BO->getOpcode();
14281428

1429-
// If this is a shift recurrence, we know the bits being shifted in.
1430-
// We can combine that with information about the start value of the
1431-
// recurrence to conclude facts about the result.
14321429
switch (Opcode) {
1430+
// If this is a shift recurrence, we know the bits being shifted in. We
1431+
// can combine that with information about the start value of the
1432+
// recurrence to conclude facts about the result. If this is a udiv
1433+
// recurrence, we know that the result can never exceed either the
1434+
// numerator or the start value, whichever is greater.
14331435
case Instruction::LShr:
14341436
case Instruction::AShr:
1435-
case Instruction::Shl: {
1437+
case Instruction::Shl:
1438+
case Instruction::UDiv:
14361439
if (BO->getOperand(0) != I)
14371440
break;
1441+
[[fallthrough]];
14381442

1443+
// For a urem recurrence, the result can never exceed the start value. The
1444+
// phi could either be the numerator or the denominator.
1445+
case Instruction::URem: {
14391446
// We have matched a recurrence of the form:
14401447
// %iv = [R, %entry], [%iv.next, %backedge]
14411448
// %iv.next = shift_op %iv, L
@@ -1453,8 +1460,10 @@ static void computeKnownBitsFromOperator(const Operator *I,
14531460
Known.Zero.setLowBits(Known2.countMinTrailingZeros());
14541461
break;
14551462
case Instruction::LShr:
1456-
// A lshr recurrence will preserve the leading zeros of the
1457-
// start value
1463+
case Instruction::UDiv:
1464+
case Instruction::URem:
1465+
// lshr, udiv, and urem recurrences will preserve the leading zeros of
1466+
// the start value.
14581467
Known.Zero.setHighBits(Known2.countMinLeadingZeros());
14591468
break;
14601469
case Instruction::AShr:
@@ -1542,6 +1551,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
15421551
}
15431552
break;
15441553
}
1554+
15451555
default:
15461556
break;
15471557
}
@@ -9039,12 +9049,14 @@ bool llvm::matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO,
90399049
switch (Opcode) {
90409050
default:
90419051
continue;
9042-
// TODO: Expand list -- xor, div, gep, uaddo, etc..
9052+
// TODO: Expand list -- xor, gep, uadd.sat etc.
90439053
case Instruction::LShr:
90449054
case Instruction::AShr:
90459055
case Instruction::Shl:
90469056
case Instruction::Add:
90479057
case Instruction::Sub:
9058+
case Instruction::UDiv:
9059+
case Instruction::URem:
90489060
case Instruction::And:
90499061
case Instruction::Or:
90509062
case Instruction::Mul:

llvm/test/Analysis/ValueTracking/recurrence-knownbits.ll

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,9 @@ define i64 @test_udiv(i1 %c) {
8686
; CHECK-NEXT: entry:
8787
; CHECK-NEXT: br label [[LOOP:%.*]]
8888
; CHECK: loop:
89-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 9, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
90-
; CHECK-NEXT: [[IV_NEXT]] = udiv i64 [[IV]], 3
9189
; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP]]
9290
; CHECK: exit:
93-
; CHECK-NEXT: [[RES:%.*]] = and i64 [[IV]], 16
94-
; CHECK-NEXT: ret i64 [[RES]]
91+
; CHECK-NEXT: ret i64 0
9592
;
9693
entry:
9794
br label %loop
@@ -132,12 +129,9 @@ define i64 @test_urem(i1 %c) {
132129
; CHECK-NEXT: entry:
133130
; CHECK-NEXT: br label [[LOOP:%.*]]
134131
; CHECK: loop:
135-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 3, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
136-
; CHECK-NEXT: [[IV_NEXT]] = urem i64 9, [[IV]]
137132
; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP]]
138133
; CHECK: exit:
139-
; CHECK-NEXT: [[RES:%.*]] = and i64 [[IV]], 4
140-
; CHECK-NEXT: ret i64 [[RES]]
134+
; CHECK-NEXT: ret i64 0
141135
;
142136
entry:
143137
br label %loop

0 commit comments

Comments
 (0)