Skip to content

Commit 61f06ce

Browse files
committed
Use matchSimpleRecurrence.
1 parent 58b04aa commit 61f06ce

File tree

2 files changed

+34
-39
lines changed

2 files changed

+34
-39
lines changed

llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,30 +1004,22 @@ Instruction *InstCombinerImpl::foldPHIArgOpIntoPHI(PHINode &PN) {
10041004
///
10051005
/// For now, we require init1, init2, constant1 and constant2 to be constants.
10061006
Instruction *InstCombinerImpl::foldPHIReduction(PHINode &PN) {
1007-
// For now, only handle PHIs with one use and exactly two incoming values.
1008-
if (!PN.hasOneUse() || PN.getNumIncomingValues() != 2)
1009-
return nullptr;
1010-
1011-
// Find the binop that uses PN and ensure it can be reassociated.
1012-
auto *BO1 = dyn_cast<BinaryOperator>(PN.user_back());
1013-
if (!BO1 || !BO1->hasNUses(2) || !BO1->isAssociative())
1014-
return nullptr;
1007+
BinaryOperator *BO1;
1008+
Value *Start1;
1009+
Value *Step1;
10151010

1016-
// Ensure PN has an incoming value for BO1.
1017-
if (PN.getIncomingValue(0) != BO1 && PN.getIncomingValue(1) != BO1)
1011+
// Find the first recurrence.
1012+
if (!PN.hasOneUse() || !matchSimpleRecurrence(&PN, BO1, Start1, Step1))
10181013
return nullptr;
10191014

1020-
// Find the initial value of PN.
1021-
auto *Init1 =
1022-
dyn_cast<Constant>(PN.getIncomingValue(PN.getIncomingValue(0) == BO1));
1023-
if (!Init1)
1015+
// Ensure BO1 has two uses (PN and the reduction op) and can be reassociated.
1016+
if (!BO1->hasNUses(2) || !BO1->isAssociative())
10241017
return nullptr;
10251018

1026-
// Find the constant operand of BO1.
1027-
assert((BO1->getOperand(0) == &PN || BO1->getOperand(1) == &PN) &&
1028-
"Unexpected operand!");
1029-
auto *C1 = dyn_cast<Constant>(BO1->getOperand(BO1->getOperand(0) == &PN));
1030-
if (!C1)
1019+
// Convert Start1 and Step1 to constants.
1020+
auto *Init1 = dyn_cast<Constant>(Start1);
1021+
auto *C1 = dyn_cast<Constant>(Step1);
1022+
if (!Init1 || !C1)
10311023
return nullptr;
10321024

10331025
// Find the reduction operation.
@@ -1050,26 +1042,21 @@ Instruction *InstCombinerImpl::foldPHIReduction(PHINode &PN) {
10501042
BO2->getOpcode() != Opc || BO2->getParent() != BO1->getParent())
10511043
return nullptr;
10521044

1053-
// Find the interleaved PHI and recurrence constant.
1054-
auto *PN2 = dyn_cast<PHINode>(BO2->getOperand(0));
1055-
auto *C2 = dyn_cast<Constant>(BO2->getOperand(1));
1056-
if (!PN2 && !C2) {
1057-
PN2 = dyn_cast<PHINode>(BO2->getOperand(1));
1058-
C2 = dyn_cast<Constant>(BO2->getOperand(0));
1059-
}
1060-
if (!PN2 || !C2 || !PN2->hasOneUse() || PN2->getParent() != PN.getParent())
1045+
// Find the interleaved PHI and recurrence constants.
1046+
PHINode *PN2;
1047+
Value *Start2;
1048+
Value *Step2;
1049+
if (!matchSimpleRecurrence(BO2, PN2, Start2, Step2) || !PN2->hasOneUse() ||
1050+
PN2->getParent() != PN.getParent())
10611051
return nullptr;
1052+
10621053
assert(PN2->getNumIncomingValues() == PN.getNumIncomingValues() &&
10631054
"Expected PHIs with the same number of incoming values!");
10641055

1065-
// Ensure PN2 has an incoming value for BO2.
1066-
if (PN2->getIncomingValue(0) != BO2 && PN2->getIncomingValue(1) != BO2)
1067-
return nullptr;
1068-
1069-
// Find the initial value of PN2.
1070-
auto *Init2 = dyn_cast<Constant>(
1071-
PN2->getIncomingValue(PN2->getIncomingValue(0) == BO2));
1072-
if (!Init2)
1056+
// Convert Start2 and Step2 to constants.
1057+
auto *Init2 = dyn_cast<Constant>(Start2);
1058+
auto *C2 = dyn_cast<Constant>(Step2);
1059+
if (!Init2 || !C2)
10731060
return nullptr;
10741061

10751062
assert(BO1->isCommutative() && BO2->isCommutative() && Rdx->isCommutative() &&

llvm/test/Transforms/InstCombine/phi-reduction-chain.ll

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -475,19 +475,23 @@ exit:
475475
}
476476

477477
; Reassociate xor.
478+
; FIXME: Not currently matched by matchSimpleRecurrence.
478479
define i8 @xor_reassoc(i32 %n) {
479480
; CHECK-LABEL: define i8 @xor_reassoc(
480481
; CHECK-SAME: i32 [[N:%.*]]) {
481482
; CHECK-NEXT: [[ENTRY:.*]]:
482483
; CHECK-NEXT: br label %[[BODY:.*]]
483484
; CHECK: [[BODY]]:
484485
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]
485-
; CHECK-NEXT: [[PN:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]
486-
; CHECK-NEXT: [[RDX]] = xor i8 [[PN]], 4
486+
; CHECK-NEXT: [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]
487+
; CHECK-NEXT: [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]
488+
; CHECK-NEXT: [[OP1]] = xor i8 [[PN]], 3
489+
; CHECK-NEXT: [[OP2]] = xor i8 [[PN2]], 7
487490
; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1
488491
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]
489492
; CHECK-NEXT: br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]
490493
; CHECK: [[EXIT]]:
494+
; CHECK-NEXT: [[RDX:%.*]] = xor i8 [[OP2]], [[OP1]]
491495
; CHECK-NEXT: ret i8 [[RDX]]
492496
;
493497
entry:
@@ -509,19 +513,23 @@ exit:
509513
}
510514

511515
; Reassociate fadd if reassoc and nsz are present on all instructions.
516+
; FIXME: Not currently matched by matchSimpleRecurrence.
512517
define float @fadd_reassoc_nsz(i32 %n) {
513518
; CHECK-LABEL: define float @fadd_reassoc_nsz(
514519
; CHECK-SAME: i32 [[N:%.*]]) {
515520
; CHECK-NEXT: [[ENTRY:.*]]:
516521
; CHECK-NEXT: br label %[[BODY:.*]]
517522
; CHECK: [[BODY]]:
518523
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]
519-
; CHECK-NEXT: [[PN:%.*]] = phi float [ 1.000000e+00, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]
520-
; CHECK-NEXT: [[RDX]] = fadd reassoc nsz float [[PN]], 5.000000e+00
524+
; CHECK-NEXT: [[PN:%.*]] = phi float [ 0.000000e+00, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]
525+
; CHECK-NEXT: [[PN2:%.*]] = phi float [ 1.000000e+00, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]
526+
; CHECK-NEXT: [[OP1]] = fadd reassoc nsz float [[PN]], 2.000000e+00
527+
; CHECK-NEXT: [[OP2]] = fadd reassoc nsz float [[PN2]], 3.000000e+00
521528
; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1
522529
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]
523530
; CHECK-NEXT: br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]
524531
; CHECK: [[EXIT]]:
532+
; CHECK-NEXT: [[RDX:%.*]] = fadd reassoc nsz float [[OP2]], [[OP1]]
525533
; CHECK-NEXT: ret float [[RDX]]
526534
;
527535
entry:

0 commit comments

Comments
 (0)