Skip to content

Commit 86eda72

Browse files
authored
Merge pull request #9804 from citymarina/cherry-pick-instcombine-phi
[InstCombine] Make backedge check in op of phi transform more precise
2 parents 18e9754 + ab777c8 commit 86eda72

File tree

5 files changed

+70
-17
lines changed

5 files changed

+70
-17
lines changed

llvm/include/llvm/Transforms/InstCombine/InstCombiner.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
8484
// combining and will be updated to reflect any changes.
8585
LoopInfo *LI;
8686

87+
ReversePostOrderTraversal<BasicBlock *> &RPOT;
88+
8789
bool MadeIRChange = false;
8890

8991
/// Edges that are known to never be taken.
@@ -92,18 +94,25 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
9294
/// Order of predecessors to canonicalize phi nodes towards.
9395
SmallDenseMap<BasicBlock *, SmallVector<BasicBlock *>, 8> PredOrder;
9496

97+
/// Backedges, used to avoid pushing instructions across backedges in cases
98+
/// where this may result in infinite combine loops. For irreducible loops
99+
/// this picks an arbitrary backedge.
100+
SmallDenseSet<std::pair<const BasicBlock *, const BasicBlock *>, 8> BackEdges;
101+
bool ComputedBackEdges = false;
102+
95103
public:
96104
InstCombiner(InstructionWorklist &Worklist, BuilderTy &Builder,
97105
bool MinimizeSize, AAResults *AA, AssumptionCache &AC,
98106
TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
99107
DominatorTree &DT, OptimizationRemarkEmitter &ORE,
100108
BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI,
101-
ProfileSummaryInfo *PSI, const DataLayout &DL, LoopInfo *LI)
109+
ProfileSummaryInfo *PSI, const DataLayout &DL, LoopInfo *LI,
110+
ReversePostOrderTraversal<BasicBlock *> &RPOT)
102111
: TTI(TTI), Builder(Builder), Worklist(Worklist),
103112
MinimizeSize(MinimizeSize), AA(AA), AC(AC), TLI(TLI), DT(DT), DL(DL),
104113
SQ(DL, &TLI, &DT, &AC, nullptr, /*UseInstrInfo*/ true,
105114
/*CanUseUndef*/ true, &DC),
106-
ORE(ORE), BFI(BFI), BPI(BPI), PSI(PSI), LI(LI) {}
115+
ORE(ORE), BFI(BFI), BPI(BPI), PSI(PSI), LI(LI), RPOT(RPOT) {}
107116

108117
virtual ~InstCombiner() = default;
109118

@@ -359,6 +368,13 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
359368
std::function<void(Instruction *, unsigned, APInt, APInt &)>
360369
SimplifyAndSetOp);
361370

371+
void computeBackEdges();
372+
bool isBackEdge(const BasicBlock *From, const BasicBlock *To) {
373+
if (!ComputedBackEdges)
374+
computeBackEdges();
375+
return BackEdges.contains({From, To});
376+
}
377+
362378
/// Inserts an instruction \p New before instruction \p Old
363379
///
364380
/// Also adds the new instruction to the worklist and returns \p New so that

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
6868
TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
6969
DominatorTree &DT, OptimizationRemarkEmitter &ORE,
7070
BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI,
71-
ProfileSummaryInfo *PSI, const DataLayout &DL, LoopInfo *LI)
71+
ProfileSummaryInfo *PSI, const DataLayout &DL, LoopInfo *LI,
72+
ReversePostOrderTraversal<BasicBlock *> &RPOT)
7273
: InstCombiner(Worklist, Builder, MinimizeSize, AA, AC, TLI, TTI, DT, ORE,
73-
BFI, BPI, PSI, DL, LI) {}
74+
BFI, BPI, PSI, DL, LI, RPOT) {}
7475

7576
virtual ~InstCombinerImpl() = default;
7677

7778
/// Perform early cleanup and prepare the InstCombine worklist.
78-
bool prepareWorklist(Function &F,
79-
ReversePostOrderTraversal<BasicBlock *> &RPOT);
79+
bool prepareWorklist(Function &F);
8080

8181
/// Run the combiner over the entire worklist until it is empty.
8282
///

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,12 +1812,10 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
18121812
if (cast<Instruction>(InVal)->getParent() == NonSimplifiedBB)
18131813
return nullptr;
18141814

1815-
// If the incoming non-constant value is reachable from the phis block,
1816-
// we'll push the operation across a loop backedge. This could result in
1815+
// Do not push the operation across a loop backedge. This could result in
18171816
// an infinite combine loop, and is generally non-profitable (especially
18181817
// if the operation was originally outside the loop).
1819-
if (isPotentiallyReachable(PN->getParent(), NonSimplifiedBB, nullptr, &DT,
1820-
LI))
1818+
if (isBackEdge(NonSimplifiedBB, PN->getParent()))
18211819
return nullptr;
18221820
}
18231821

@@ -5235,8 +5233,7 @@ class AliasScopeTracker {
52355233
/// them to the worklist (this significantly speeds up instcombine on code where
52365234
/// many instructions are dead or constant). Additionally, if we find a branch
52375235
/// whose condition is a known constant, we only visit the reachable successors.
5238-
bool InstCombinerImpl::prepareWorklist(
5239-
Function &F, ReversePostOrderTraversal<BasicBlock *> &RPOT) {
5236+
bool InstCombinerImpl::prepareWorklist(Function &F) {
52405237
bool MadeIRChange = false;
52415238
SmallPtrSet<BasicBlock *, 32> LiveBlocks;
52425239
SmallVector<Instruction *, 128> InstrsForInstructionWorklist;
@@ -5375,6 +5372,18 @@ bool InstCombinerImpl::prepareWorklist(
53755372
return MadeIRChange;
53765373
}
53775374

5375+
void InstCombiner::computeBackEdges() {
5376+
// Collect backedges.
5377+
SmallPtrSet<BasicBlock *, 16> Visited;
5378+
for (BasicBlock *BB : RPOT) {
5379+
Visited.insert(BB);
5380+
for (BasicBlock *Succ : successors(BB))
5381+
if (Visited.contains(Succ))
5382+
BackEdges.insert({BB, Succ});
5383+
}
5384+
ComputedBackEdges = true;
5385+
}
5386+
53785387
static bool combineInstructionsOverFunction(
53795388
Function &F, InstructionWorklist &Worklist, AliasAnalysis *AA,
53805389
AssumptionCache &AC, TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
@@ -5418,9 +5427,9 @@ static bool combineInstructionsOverFunction(
54185427
<< F.getName() << "\n");
54195428

54205429
InstCombinerImpl IC(Worklist, Builder, F.hasMinSize(), AA, AC, TLI, TTI, DT,
5421-
ORE, BFI, BPI, PSI, DL, LI);
5430+
ORE, BFI, BPI, PSI, DL, LI, RPOT);
54225431
IC.MaxArraySizeForCombine = MaxArraySize;
5423-
bool MadeChangeInThisIteration = IC.prepareWorklist(F, RPOT);
5432+
bool MadeChangeInThisIteration = IC.prepareWorklist(F);
54245433
MadeChangeInThisIteration |= IC.run();
54255434
if (!MadeChangeInThisIteration)
54265435
break;

llvm/test/Transforms/InstCombine/phi.ll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2742,3 +2742,31 @@ for.cond: ; preds = %for.cond, %entry
27422742
exit: ; preds = %for.cond
27432743
ret i64 0
27442744
}
2745+
2746+
define void @phi_op_in_loop(i1 %c, i32 %x) {
2747+
; CHECK-LABEL: @phi_op_in_loop(
2748+
; CHECK-NEXT: br label [[LOOP:%.*]]
2749+
; CHECK: loop:
2750+
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[LOOP_LATCH:%.*]]
2751+
; CHECK: if:
2752+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 1
2753+
; CHECK-NEXT: br label [[LOOP_LATCH]]
2754+
; CHECK: loop.latch:
2755+
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[TMP1]], [[IF]] ], [ 0, [[LOOP]] ]
2756+
; CHECK-NEXT: call void @use(i32 [[PHI]])
2757+
; CHECK-NEXT: br label [[LOOP]]
2758+
;
2759+
br label %loop
2760+
2761+
loop:
2762+
br i1 %c, label %if, label %loop.latch
2763+
2764+
if:
2765+
br label %loop.latch
2766+
2767+
loop.latch:
2768+
%phi = phi i32 [ %x, %if ], [ 0, %loop ]
2769+
%and = and i32 %phi, 1
2770+
call void @use(i32 %and)
2771+
br label %loop
2772+
}

llvm/test/Transforms/LoopVectorize/induction.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5504,11 +5504,11 @@ define i32 @PR32419(i32 %a, i16 %b) {
55045504
; INTERLEAVE-NEXT: br i1 [[VAR2]], label [[FOR_INC]], label [[FOR_COND:%.*]]
55055505
; INTERLEAVE: for.cond:
55065506
; INTERLEAVE-NEXT: [[VAR3:%.*]] = urem i16 [[B]], [[VAR1]]
5507+
; INTERLEAVE-NEXT: [[TMP50:%.*]] = sext i16 [[VAR3]] to i32
55075508
; INTERLEAVE-NEXT: br label [[FOR_INC]]
55085509
; INTERLEAVE: for.inc:
5509-
; INTERLEAVE-NEXT: [[VAR4:%.*]] = phi i16 [ [[VAR3]], [[FOR_COND]] ], [ 0, [[FOR_BODY]] ]
5510-
; INTERLEAVE-NEXT: [[VAR5:%.*]] = sext i16 [[VAR4]] to i32
5511-
; INTERLEAVE-NEXT: [[VAR6]] = or i32 [[VAR0]], [[VAR5]]
5510+
; INTERLEAVE-NEXT: [[VAR4:%.*]] = phi i32 [ [[TMP50]], [[FOR_COND]] ], [ 0, [[FOR_BODY]] ]
5511+
; INTERLEAVE-NEXT: [[VAR6]] = or i32 [[VAR0]], [[VAR4]]
55125512
; INTERLEAVE-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
55135513
; INTERLEAVE-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], 0
55145514
; INTERLEAVE-NEXT: br i1 [[COND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP49:![0-9]+]]

0 commit comments

Comments
 (0)