Skip to content

Commit

Permalink
[InstCombine] Fold extractvalue of phi
Browse files Browse the repository at this point in the history
Just as we do for most other operations, we should push
extractvalue instructions through phis, if this does not increase
unfolded instruction count.
  • Loading branch information
nikic committed Sep 1, 2022
1 parent 5b219dd commit 43e7d9a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
9 changes: 9 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,11 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
InV = PN->getIncomingValue(i);
NewPN->addIncoming(InV, PN->getIncomingBlock(i));
}
} else if (auto *EV = dyn_cast<ExtractValueInst>(&I)) {
for (unsigned i = 0; i != NumPHIValues; ++i)
NewPN->addIncoming(Builder.CreateExtractValue(PN->getIncomingValue(i),
EV->getIndices(), "phi.ev"),
PN->getIncomingBlock(i));
} else {
CastInst *CI = cast<CastInst>(&I);
Type *RetTy = CI->getType();
Expand Down Expand Up @@ -3399,6 +3404,10 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
}
}

if (auto *PN = dyn_cast<PHINode>(Agg))
if (Instruction *Res = foldOpIntoPhi(EV, PN))
return Res;

// We could simplify extracts from other values. Note that nested extracts may
// already be simplified implicitly by the above: extract (extract (insert) )
// will be translated into extract ( insert ( extract ) ) first and then just
Expand Down
22 changes: 10 additions & 12 deletions llvm/test/Transforms/InstCombine/phi-extractvalue.ll
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,8 @@ define i32 @extractvalue_of_constant_phi(i1 %c) {
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = phi { i32, i32 } [ { i32 1, i32 2 }, [[IF]] ], [ { i32 3, i32 4 }, [[ELSE]] ]
; CHECK-NEXT: [[EV:%.*]] = extractvalue { i32, i32 } [[PHI]], 0
; CHECK-NEXT: ret i32 [[EV]]
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF]] ], [ 3, [[ELSE]] ]
; CHECK-NEXT: ret i32 [[PHI]]
;
br i1 %c, label %if, label %else

Expand All @@ -415,13 +414,13 @@ define i32 @extractvalue_of_one_constant_phi(i1 %c, { i32, i32 } %arg) {
; CHECK-LABEL: @extractvalue_of_one_constant_phi(
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: [[PHI_EV:%.*]] = extractvalue { i32, i32 } [[ARG:%.*]], 0
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = phi { i32, i32 } [ [[ARG:%.*]], [[IF]] ], [ { i32 3, i32 4 }, [[ELSE]] ]
; CHECK-NEXT: [[EV:%.*]] = extractvalue { i32, i32 } [[PHI]], 0
; CHECK-NEXT: ret i32 [[EV]]
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[PHI_EV]], [[IF]] ], [ 3, [[ELSE]] ]
; CHECK-NEXT: ret i32 [[PHI]]
;
br i1 %c, label %if, label %else

Expand All @@ -445,9 +444,8 @@ define i32 @extractvalue_of_constant_phi_multi_index(i1 %c) {
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = phi { i32, { i32, i32 } } [ { i32 1, { i32, i32 } { i32 2, i32 3 } }, [[IF]] ], [ { i32 4, { i32, i32 } { i32 5, i32 6 } }, [[ELSE]] ]
; CHECK-NEXT: [[EV:%.*]] = extractvalue { i32, { i32, i32 } } [[PHI]], 1, 1
; CHECK-NEXT: ret i32 [[EV]]
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 3, [[IF]] ], [ 6, [[ELSE]] ]
; CHECK-NEXT: ret i32 [[PHI]]
;
br i1 %c, label %if, label %else

Expand All @@ -467,13 +465,13 @@ define i32 @extractvalue_of_one_constant_phi_multi_index(i1 %c, { i32, { i32, i3
; CHECK-LABEL: @extractvalue_of_one_constant_phi_multi_index(
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: [[PHI_EV:%.*]] = extractvalue { i32, { i32, i32 } } [[ARG:%.*]], 1, 1
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = phi { i32, { i32, i32 } } [ [[ARG:%.*]], [[IF]] ], [ { i32 4, { i32, i32 } { i32 5, i32 6 } }, [[ELSE]] ]
; CHECK-NEXT: [[EV:%.*]] = extractvalue { i32, { i32, i32 } } [[PHI]], 1, 1
; CHECK-NEXT: ret i32 [[EV]]
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[PHI_EV]], [[IF]] ], [ 6, [[ELSE]] ]
; CHECK-NEXT: ret i32 [[PHI]]
;
br i1 %c, label %if, label %else

Expand Down

0 comments on commit 43e7d9a

Please sign in to comment.