Skip to content

Commit c849748

Browse files
committed
[InstCombine] Simplify phi using KnownBits of condition
Simplify the arms of a phi based on the KnownBits implied by the condition for the predecessor basic block.
1 parent 449e2f5 commit c849748

32 files changed

+280
-384
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -840,16 +840,27 @@ void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
840840

841841
if (Q.DC && Q.DT) {
842842
// Handle dominating conditions.
843-
for (BranchInst *BI : Q.DC->conditionsFor(V)) {
844-
BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
845-
if (Q.DT->dominates(Edge0, Q.CxtI->getParent()))
846-
computeKnownBitsFromCond(V, BI->getCondition(), Known, Depth, Q,
847-
/*Invert*/ false);
843+
const BasicBlock *CxtIBB = Q.CxtI->getParent();
844+
if (isa<PHINode>(Q.CxtI))
845+
for (BranchInst *BI : Q.DC->conditionsFor(V)) {
846+
if (BI->getSuccessor(0) != CxtIBB && BI->getSuccessor(1) != CxtIBB)
847+
continue;
848848

849-
BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
850-
if (Q.DT->dominates(Edge1, Q.CxtI->getParent()))
849+
bool Invert = BI->getSuccessor(1) == CxtIBB;
851850
computeKnownBitsFromCond(V, BI->getCondition(), Known, Depth, Q,
852-
/*Invert*/ true);
851+
Invert);
852+
}
853+
else
854+
for (BranchInst *BI : Q.DC->conditionsFor(V)) {
855+
BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
856+
if (Q.DT->dominates(Edge0, CxtIBB))
857+
computeKnownBitsFromCond(V, BI->getCondition(), Known, Depth, Q,
858+
/*Invert*/ false);
859+
860+
BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
861+
if (Q.DT->dominates(Edge1, CxtIBB))
862+
computeKnownBitsFromCond(V, BI->getCondition(), Known, Depth, Q,
863+
/*Invert*/ true);
853864
}
854865

855866
if (Known.hasConflict())

llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,25 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
16251625
return replaceInstUsesWith(PN, &IdenticalPN);
16261626
}
16271627

1628+
if (PN.getType()->isIntegerTy()) {
1629+
bool MadeChange = false;
1630+
SimplifyQuery Q = SQ.getWithInstruction(&PN);
1631+
for (unsigned I = 0, E = PN.getNumIncomingValues(); I != E; ++I) {
1632+
Value *V = PN.getIncomingValue(I);
1633+
if (isa<ConstantInt>(V))
1634+
continue;
1635+
1636+
KnownBits Known = llvm::computeKnownBits(V, /* Depth */ 0, Q);
1637+
if (Known.isConstant()) {
1638+
replaceOperand(PN, I,
1639+
ConstantInt::get(V->getType(), Known.getConstant()));
1640+
MadeChange = true;
1641+
}
1642+
}
1643+
if (MadeChange)
1644+
return &PN;
1645+
}
1646+
16281647
// If this is an integer PHI and we know that it has an illegal type, see if
16291648
// it is only used by trunc or trunc(lshr) operations. If so, we split the
16301649
// PHI into the various pieces being extracted. This sort of thing is

llvm/test/Transforms/InstCombine/fold-aggregate-reconstruction.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ define {ptr, i64} @test4(i1 %cond1, i1 %cond2, ptr %p1, ptr %p2) {
178178
; CHECK-NEXT: br i1 [[COND3_NOT]], label %[[EXIT]], label %[[BBB4]]
179179
; CHECK: [[EXIT]]:
180180
; CHECK-NEXT: [[VAL1:%.*]] = phi ptr [ [[VAL11]], %[[BBB2]] ], [ [[VAL21]], %[[BBB3]] ], [ [[VAL31]], %[[BBB4]] ]
181-
; CHECK-NEXT: [[VAL2:%.*]] = phi i64 [ [[VAL12]], %[[BBB2]] ], [ [[VAL22]], %[[BBB3]] ], [ [[VAL32]], %[[BBB4]] ]
181+
; CHECK-NEXT: [[VAL2:%.*]] = phi i64 [ [[VAL12]], %[[BBB2]] ], [ [[VAL22]], %[[BBB3]] ], [ 0, %[[BBB4]] ]
182182
; CHECK-NEXT: [[TMP:%.*]] = insertvalue { ptr, i64 } poison, ptr [[VAL1]], 0
183183
; CHECK-NEXT: [[RES:%.*]] = insertvalue { ptr, i64 } [[TMP]], i64 [[VAL2]], 1
184184
; CHECK-NEXT: ret { ptr, i64 } [[RES]]

llvm/test/Transforms/InstCombine/known-phi-br.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ define i64 @limit_i64_eq_7(i64 %x) {
1515
; CHECK: body:
1616
; CHECK-NEXT: br label [[END]]
1717
; CHECK: end:
18-
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ 7, [[BODY]] ]
19-
; CHECK-NEXT: ret i64 [[RES]]
18+
; CHECK-NEXT: ret i64 7
2019
;
2120
entry:
2221
%cmp = icmp eq i64 %x, 7
@@ -38,8 +37,7 @@ define i64 @limit_i64_ne_255(i64 %x) {
3837
; CHECK: body:
3938
; CHECK-NEXT: br label [[END]]
4039
; CHECK: end:
41-
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ 255, [[BODY]] ]
42-
; CHECK-NEXT: ret i64 [[RES]]
40+
; CHECK-NEXT: ret i64 255
4341
;
4442
entry:
4543
%cmp = icmp ne i64 %x, 255

llvm/test/Transforms/LoopVectorize/AArch64/deterministic-type-shrinkage.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,10 @@ define void @test_pr25490(i32 %n, ptr noalias nocapture %a, ptr noalias nocaptur
5454
; CHECK-NEXT: [[MIN_EPILOG_ITERS_CHECK:%.*]] = icmp eq i64 [[N_VEC_REMAINING]], 0
5555
; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]]
5656
; CHECK: vec.epilog.ph:
57-
; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ]
5857
; CHECK-NEXT: [[N_VEC5:%.*]] = and i64 [[TMP0]], 4294967292
5958
; CHECK-NEXT: br label [[VEC_EPILOG_VECTOR_BODY:%.*]]
6059
; CHECK: vec.epilog.vector.body:
61-
; CHECK-NEXT: [[INDEX6:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT10:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
60+
; CHECK-NEXT: [[INDEX6:%.*]] = phi i64 [ 0, [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT10:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
6261
; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 [[INDEX6]]
6362
; CHECK-NEXT: [[WIDE_LOAD7:%.*]] = load <4 x i8>, ptr [[TMP14]], align 1
6463
; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDEX6]]
@@ -83,14 +82,13 @@ define void @test_pr25490(i32 %n, ptr noalias nocapture %a, ptr noalias nocaptur
8382
; CHECK-NEXT: [[CMP_N11:%.*]] = icmp eq i64 [[N_VEC5]], [[TMP0]]
8483
; CHECK-NEXT: br i1 [[CMP_N11]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[VEC_EPILOG_SCALAR_PH]]
8584
; CHECK: vec.epilog.scalar.ph:
86-
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC5]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[ITER_CHECK]] ]
8785
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
8886
; CHECK: for.cond.cleanup.loopexit:
8987
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
9088
; CHECK: for.cond.cleanup:
9189
; CHECK-NEXT: ret void
9290
; CHECK: for.body:
93-
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[VEC_EPILOG_SCALAR_PH]] ]
91+
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[VEC_EPILOG_SCALAR_PH]] ]
9492
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[C]], i64 [[INDVARS_IV]]
9593
; CHECK-NEXT: [[TMP27:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
9694
; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[TMP27]] to i32

llvm/test/Transforms/LoopVectorize/AArch64/intrinsiccost.ll

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
77
target triple = "aarch64--linux-gnu"
88

99
; CHECK-COST-LABEL: sadd
10-
; CHECK-COST: Found an estimated cost of 6 for VF 1 For instruction: %1 = tail call i16 @llvm.sadd.sat.i16(i16 %0, i16 %offset)
11-
; CHECK-COST: Cost of 4 for VF 2: WIDEN-INTRINSIC ir<%1> = call llvm.sadd.sat(ir<%0>, ir<%offset>)
12-
; CHECK-COST: Cost of 1 for VF 4: WIDEN-INTRINSIC ir<%1> = call llvm.sadd.sat(ir<%0>, ir<%offset>)
13-
; CHECK-COST: Cost of 1 for VF 8: WIDEN-INTRINSIC ir<%1> = call llvm.sadd.sat(ir<%0>, ir<%offset>)
1410

1511
define void @saddsat(ptr nocapture readonly %pSrc, i16 signext %offset, ptr nocapture noalias %pDst, i32 %blockSize) #0 {
1612
; CHECK-LABEL: @saddsat(
@@ -60,7 +56,6 @@ define void @saddsat(ptr nocapture readonly %pSrc, i16 signext %offset, ptr noca
6056
; CHECK-NEXT: [[MIN_EPILOG_ITERS_CHECK:%.*]] = icmp eq i64 [[N_VEC_REMAINING]], 0
6157
; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]]
6258
; CHECK: vec.epilog.ph:
63-
; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ]
6459
; CHECK-NEXT: [[N_VEC6:%.*]] = and i64 [[TMP0]], 4294967292
6560
; CHECK-NEXT: [[DOTCAST:%.*]] = trunc nuw i64 [[N_VEC6]] to i32
6661
; CHECK-NEXT: [[IND_END:%.*]] = sub i32 [[BLOCKSIZE]], [[DOTCAST]]
@@ -72,7 +67,7 @@ define void @saddsat(ptr nocapture readonly %pSrc, i16 signext %offset, ptr noca
7267
; CHECK-NEXT: [[BROADCAST_SPLAT22:%.*]] = shufflevector <4 x i16> [[BROADCAST_SPLATINSERT21]], <4 x i16> poison, <4 x i32> zeroinitializer
7368
; CHECK-NEXT: br label [[VEC_EPILOG_VECTOR_BODY:%.*]]
7469
; CHECK: vec.epilog.vector.body:
75-
; CHECK-NEXT: [[INDEX15:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT23:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
70+
; CHECK-NEXT: [[INDEX15:%.*]] = phi i64 [ 0, [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT23:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
7671
; CHECK-NEXT: [[OFFSET_IDX16:%.*]] = shl i64 [[INDEX15]], 1
7772
; CHECK-NEXT: [[NEXT_GEP17:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[OFFSET_IDX16]]
7873
; CHECK-NEXT: [[OFFSET_IDX18:%.*]] = shl i64 [[INDEX15]], 1
@@ -128,11 +123,6 @@ while.end: ; preds = %while.body, %entry
128123
}
129124

130125
; CHECK-COST-LABEL: umin
131-
; CHECK-COST: Found an estimated cost of 2 for VF 1 For instruction: %1 = tail call i8 @llvm.umin.i8(i8 %0, i8 %offset)
132-
; CHECK-COST: Cost of 1 for VF 2: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
133-
; CHECK-COST: Cost of 1 for VF 4: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
134-
; CHECK-COST: Cost of 1 for VF 8: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
135-
; CHECK-COST: Cost of 1 for VF 16: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
136126

137127

138128
define void @umin(ptr nocapture readonly %pSrc, i8 signext %offset, ptr nocapture noalias %pDst, i32 %blockSize) #0 {
@@ -179,7 +169,6 @@ define void @umin(ptr nocapture readonly %pSrc, i8 signext %offset, ptr nocaptur
179169
; CHECK-NEXT: [[MIN_EPILOG_ITERS_CHECK:%.*]] = icmp eq i64 [[N_VEC_REMAINING]], 0
180170
; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]]
181171
; CHECK: vec.epilog.ph:
182-
; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ]
183172
; CHECK-NEXT: [[N_VEC5:%.*]] = and i64 [[TMP0]], 4294967288
184173
; CHECK-NEXT: [[DOTCAST:%.*]] = trunc nuw i64 [[N_VEC5]] to i32
185174
; CHECK-NEXT: [[IND_END:%.*]] = sub i32 [[BLOCKSIZE]], [[DOTCAST]]
@@ -189,7 +178,7 @@ define void @umin(ptr nocapture readonly %pSrc, i8 signext %offset, ptr nocaptur
189178
; CHECK-NEXT: [[BROADCAST_SPLAT19:%.*]] = shufflevector <8 x i8> [[BROADCAST_SPLATINSERT18]], <8 x i8> poison, <8 x i32> zeroinitializer
190179
; CHECK-NEXT: br label [[VEC_EPILOG_VECTOR_BODY:%.*]]
191180
; CHECK: vec.epilog.vector.body:
192-
; CHECK-NEXT: [[INDEX14:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT20:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
181+
; CHECK-NEXT: [[INDEX14:%.*]] = phi i64 [ 0, [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT20:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
193182
; CHECK-NEXT: [[NEXT_GEP15:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[INDEX14]]
194183
; CHECK-NEXT: [[NEXT_GEP16:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[INDEX14]]
195184
; CHECK-NEXT: [[WIDE_LOAD17:%.*]] = load <8 x i8>, ptr [[NEXT_GEP15]], align 2

0 commit comments

Comments
 (0)