[llvm] 95848ea - [Value][InstCombine] Fix one-use checks in PHI-of-op -> Op-of-PHI[s] transforms to be one-user checks
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 26 10:20:57 PDT 2020
Author: Roman Lebedev
Date: 2020-08-26T20:20:41+03:00
New Revision: 95848ea101274b8bd774c63bad55f21a08080705
URL: https://github.com/llvm/llvm-project/commit/95848ea101274b8bd774c63bad55f21a08080705
DIFF: https://github.com/llvm/llvm-project/commit/95848ea101274b8bd774c63bad55f21a08080705.diff
LOG: [Value][InstCombine] Fix one-use checks in PHI-of-op -> Op-of-PHI[s] transforms to be one-user checks
As FIXME said, they really should be checking for a single user,
not use, so let's do that. It is not *that* unusual to have
the same value as incoming value in a PHI node, not unlike
how a PHI may have the same incoming basic block more than once.
There isn't a nice way to do that, Value::users() isn't uniqified,
and Value only tracks it's uses, not Users, so the check is
potentially costly since it does indeed potentially involes
traversing the entire use list of a value.
Added:
Modified:
llvm/include/llvm/IR/Value.h
llvm/lib/IR/Value.cpp
llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll
llvm/test/Transforms/InstCombine/phi-of-extractvalues.ll
llvm/test/Transforms/InstCombine/phi-of-insertvalues.ll
llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll
llvm/test/Transforms/PGOProfile/chr.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h
index 723868af729d..1ed689dc82a5 100644
--- a/llvm/include/llvm/IR/Value.h
+++ b/llvm/include/llvm/IR/Value.h
@@ -442,6 +442,16 @@ class Value {
/// This is logically equivalent to getNumUses() >= N.
bool hasNUsesOrMore(unsigned N) const;
+ /// Return true if there is exactly one user of this value.
+ ///
+ /// Note that this is not the same as "has one use". If a value has one use,
+ /// then there certainly is a single user. But if value has several uses,
+ /// it is possible that all uses are in a single user, or not.
+ ///
+ /// This check is potentially costly, since it requires traversing,
+ /// in the worst case, the whole use list of a value.
+ bool hasOneUser() const;
+
/// Return true if there is exactly one use of this value that cannot be
/// dropped.
///
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 26a983596ab2..3e5dd8fdaf98 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -147,6 +147,14 @@ bool Value::hasNUsesOrMore(unsigned N) const {
return hasNItemsOrMore(use_begin(), use_end(), N);
}
+bool Value::hasOneUser() const {
+ if (use_empty())
+ return false;
+ if (hasOneUse())
+ return true;
+ return std::equal(++user_begin(), user_end(), user_begin());
+}
+
static bool isUnDroppableUser(const User *U) { return !U->isDroppable(); }
Use *Value::getSingleUndroppableUse() {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index 4c43e835186a..d8510d5388d1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -308,7 +308,7 @@ InstCombinerImpl::foldPHIArgInsertValueInstructionIntoPHI(PHINode &PN) {
// and all have a single use.
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
auto *I = dyn_cast<InsertValueInst>(PN.getIncomingValue(i));
- if (!I || !I->hasOneUse() || I->getIndices() != FirstIVI->getIndices())
+ if (!I || !I->hasOneUser() || I->getIndices() != FirstIVI->getIndices())
return nullptr;
}
@@ -348,7 +348,7 @@ InstCombinerImpl::foldPHIArgExtractValueInstructionIntoPHI(PHINode &PN) {
// and all have a single use.
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
auto *I = dyn_cast<ExtractValueInst>(PN.getIncomingValue(i));
- if (!I || !I->hasOneUse() || I->getIndices() != FirstEVI->getIndices() ||
+ if (!I || !I->hasOneUser() || I->getIndices() != FirstEVI->getIndices() ||
I->getAggregateOperand()->getType() !=
FirstEVI->getAggregateOperand()->getType())
return nullptr;
@@ -376,7 +376,7 @@ InstCombinerImpl::foldPHIArgExtractValueInstructionIntoPHI(PHINode &PN) {
}
/// If we have something like phi [add (a,b), add(a,c)] and if a/b/c and the
-/// adds all have a single use, turn this into a phi and a single binop.
+/// adds all have a single user, turn this into a phi and a single binop.
Instruction *InstCombinerImpl::foldPHIArgBinOpIntoPHI(PHINode &PN) {
Instruction *FirstInst = cast<Instruction>(PN.getIncomingValue(0));
assert(isa<BinaryOperator>(FirstInst) || isa<CmpInst>(FirstInst));
@@ -387,10 +387,10 @@ Instruction *InstCombinerImpl::foldPHIArgBinOpIntoPHI(PHINode &PN) {
Type *LHSType = LHSVal->getType();
Type *RHSType = RHSVal->getType();
- // Scan to see if all operands are the same opcode, and all have one use.
+ // Scan to see if all operands are the same opcode, and all have one user.
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
- if (!I || I->getOpcode() != Opc || !I->hasOneUse() ||
+ if (!I || I->getOpcode() != Opc || !I->hasOneUser() ||
// Verify type of the LHS matches so we don't fold cmp's of
diff erent
// types.
I->getOperand(0)->getType() != LHSType ||
@@ -486,11 +486,12 @@ Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {
bool AllInBounds = true;
- // Scan to see if all operands are the same opcode, and all have one use.
+ // Scan to see if all operands are the same opcode, and all have one user.
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
- GetElementPtrInst *GEP= dyn_cast<GetElementPtrInst>(PN.getIncomingValue(i));
- if (!GEP || !GEP->hasOneUse() || GEP->getType() != FirstInst->getType() ||
- GEP->getNumOperands() != FirstInst->getNumOperands())
+ GetElementPtrInst *GEP =
+ dyn_cast<GetElementPtrInst>(PN.getIncomingValue(i));
+ if (!GEP || !GEP->hasOneUser() || GEP->getType() != FirstInst->getType() ||
+ GEP->getNumOperands() != FirstInst->getNumOperands())
return nullptr;
AllInBounds &= GEP->isInBounds();
@@ -657,7 +658,7 @@ Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
// Check to see if all arguments are the same operation.
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
LoadInst *LI = dyn_cast<LoadInst>(PN.getIncomingValue(i));
- if (!LI || !LI->hasOneUse())
+ if (!LI || !LI->hasOneUser())
return nullptr;
// We can't sink the load if the loaded value could be modified between
@@ -770,8 +771,8 @@ Instruction *InstCombinerImpl::foldPHIArgZextsIntoPHI(PHINode &Phi) {
unsigned NumConsts = 0;
for (Value *V : Phi.incoming_values()) {
if (auto *Zext = dyn_cast<ZExtInst>(V)) {
- // All zexts must be identical and have one use.
- if (Zext->getSrcTy() != NarrowType || !Zext->hasOneUse())
+ // All zexts must be identical and have one user.
+ if (Zext->getSrcTy() != NarrowType || !Zext->hasOneUser())
return nullptr;
NewIncoming.push_back(Zext->getOperand(0));
NumZexts++;
@@ -859,7 +860,7 @@ Instruction *InstCombinerImpl::foldPHIArgOpIntoPHI(PHINode &PN) {
// Check to see if all arguments are the same operation.
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
- if (!I || !I->hasOneUse() || !I->isSameOperationAs(FirstInst))
+ if (!I || !I->hasOneUser() || !I->isSameOperationAs(FirstInst))
return nullptr;
if (CastSrcTy) {
if (I->getOperand(0)->getType() != CastSrcTy)
@@ -1303,10 +1304,8 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
if (isa<Instruction>(PN.getIncomingValue(0)) &&
isa<Instruction>(PN.getIncomingValue(1)) &&
cast<Instruction>(PN.getIncomingValue(0))->getOpcode() ==
- cast<Instruction>(PN.getIncomingValue(1))->getOpcode() &&
- // FIXME: The hasOneUse check will fail for PHIs that use the value more
- // than themselves more than once.
- PN.getIncomingValue(0)->hasOneUse())
+ cast<Instruction>(PN.getIncomingValue(1))->getOpcode() &&
+ PN.getIncomingValue(0)->hasOneUser())
if (Instruction *Result = foldPHIArgOpIntoPHI(PN))
return Result;
diff --git a/llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll b/llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll
index 939126bd2e34..866750c27177 100644
--- a/llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll
+++ b/llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll
@@ -450,9 +450,14 @@ define { i32, i32 } @test8({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %
; CHECK: impossible:
; CHECK-NEXT: unreachable
; CHECK: end:
-; CHECK-NEXT: [[I8_MERGED:%.*]] = phi { i32, i32 } [ [[AGG_RIGHT:%.*]], [[RIGHT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ], [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_LEFT]], [[LEFT]] ]
+; CHECK-NEXT: [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ]
+; CHECK-NEXT: [[AGG_LEFT_PN1:%.*]] = phi { i32, i32 } [ [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ]
+; CHECK-NEXT: [[I6:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT_PN1]], 1
+; CHECK-NEXT: [[I5:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT_PN]], 0
; CHECK-NEXT: call void @baz()
-; CHECK-NEXT: ret { i32, i32 } [[I8_MERGED]]
+; CHECK-NEXT: [[I7:%.*]] = insertvalue { i32, i32 } undef, i32 [[I5]], 0
+; CHECK-NEXT: [[I8:%.*]] = insertvalue { i32, i32 } [[I7]], i32 [[I6]], 1
+; CHECK-NEXT: ret { i32, i32 } [[I8]]
;
entry:
br i1 %c, label %left, label %right
diff --git a/llvm/test/Transforms/InstCombine/phi-of-extractvalues.ll b/llvm/test/Transforms/InstCombine/phi-of-extractvalues.ll
index 11337c7d41e3..020b98407984 100644
--- a/llvm/test/Transforms/InstCombine/phi-of-extractvalues.ll
+++ b/llvm/test/Transforms/InstCombine/phi-of-extractvalues.ll
@@ -317,8 +317,6 @@ end:
define i32 @test10({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0, i1 %c1) {
; CHECK-LABEL: @test10(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
-; CHECK-NEXT: [[I1:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 0
; CHECK-NEXT: br i1 [[C0:%.*]], label [[END:%.*]], label [[DISPATCH:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: br i1 [[C1:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
@@ -327,7 +325,8 @@ define i32 @test10({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0, i1 %
; CHECK: right:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
-; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[I0]], [[ENTRY:%.*]] ], [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
+; CHECK-NEXT: [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[ENTRY:%.*]] ], [ [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
+; CHECK-NEXT: [[R:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT_PN]], 0
; CHECK-NEXT: ret i32 [[R]]
;
entry:
diff --git a/llvm/test/Transforms/InstCombine/phi-of-insertvalues.ll b/llvm/test/Transforms/InstCombine/phi-of-insertvalues.ll
index 51bf8e21c1c8..d6961b8b7ba1 100644
--- a/llvm/test/Transforms/InstCombine/phi-of-insertvalues.ll
+++ b/llvm/test/Transforms/InstCombine/phi-of-insertvalues.ll
@@ -288,8 +288,6 @@ end:
define { i32, i32 } @test9({ i32, i32 } %agg, i32 %val_left, i32 %val_right, i1 %c0, i1 %c1) {
; CHECK-LABEL: @test9(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[I0:%.*]] = insertvalue { i32, i32 } [[AGG:%.*]], i32 [[VAL_LEFT:%.*]], 0
-; CHECK-NEXT: [[I1:%.*]] = insertvalue { i32, i32 } [[AGG]], i32 [[VAL_RIGHT:%.*]], 0
; CHECK-NEXT: br i1 [[C0:%.*]], label [[END:%.*]], label [[DISPATCH:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: br i1 [[C1:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
@@ -298,7 +296,8 @@ define { i32, i32 } @test9({ i32, i32 } %agg, i32 %val_left, i32 %val_right, i1
; CHECK: right:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
-; CHECK-NEXT: [[R:%.*]] = phi { i32, i32 } [ [[I0]], [[ENTRY:%.*]] ], [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
+; CHECK-NEXT: [[VAL_LEFT_PN:%.*]] = phi i32 [ [[VAL_LEFT:%.*]], [[ENTRY:%.*]] ], [ [[VAL_LEFT]], [[LEFT]] ], [ [[VAL_RIGHT:%.*]], [[RIGHT]] ]
+; CHECK-NEXT: [[R:%.*]] = insertvalue { i32, i32 } [[AGG:%.*]], i32 [[VAL_LEFT_PN]], 0
; CHECK-NEXT: ret { i32, i32 } [[R]]
;
entry:
diff --git a/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll b/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll
index 7be217b06aae..d2028bb8a197 100644
--- a/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll
+++ b/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll
@@ -404,26 +404,26 @@ returnblock: ; preds = %latchExit, %entr
define i64 @test5(i64 %trip, i64 %add, i1 %cond) {
; EPILOG: test5(
; EPILOG: exit1.loopexit:
-; EPILOG-NEXT: %result.ph = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.2, %loop_exiting.2 ],
+; EPILOG-NEXT: %iv.pn = phi i64 [ %iv, %loop_exiting ], [ %iv, %loop_exiting ], [ %iv_next, %loop_exiting.1 ], [ %iv_next, %loop_exiting.1 ], [ %iv_next.1, %loop_exiting.2 ], [ %iv_next.1, %loop_exiting.2 ], [ %iv_next.2, %loop_exiting.3 ], [ %iv_next.2, %loop_exiting.3 ], [ %iv_next.3, %loop_exiting.4 ], [ %iv_next.3, %loop_exiting.4 ], [ %iv_next.4, %loop_exiting.5 ], [ %iv_next.4, %loop_exiting.5 ], [ %iv_next.5, %loop_exiting.6 ], [ %iv_next.5, %loop_exiting.6 ], [ %iv_next.6, %loop_exiting.7 ], [ %iv_next.6, %loop_exiting.7 ]
; EPILOG-NEXT: br label %exit1
; EPILOG: exit1.loopexit2:
-; EPILOG-NEXT: %ivy.epil = add i64 %iv.epil, %add
; EPILOG-NEXT: br label %exit1
; EPILOG: exit1:
-; EPILOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.epil, %exit1.loopexit2 ]
+; EPILOG-NEXT: %iv.pn.pn = phi i64 [ %iv.pn, %exit1.loopexit ], [ %iv.epil, %exit1.loopexit2 ]
+; EPILOG-NEXT: %result = add i64 %iv.pn.pn, %add
; EPILOG-NEXT: ret i64 %result
; EPILOG: loop_latch.7:
; EPILOG: %niter.nsub.7 = add i64 %niter, -8
; PROLOG: test5(
; PROLOG: exit1.loopexit:
-; PROLOG-NEXT: %result.ph = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.2, %loop_exiting.2 ],
+; PROLOG-NEXT: %iv.pn = phi i64 [ %iv, %loop_exiting ], [ %iv, %loop_exiting ], [ %iv_next, %loop_exiting.1 ], [ %iv_next, %loop_exiting.1 ], [ %iv_next.1, %loop_exiting.2 ], [ %iv_next.1, %loop_exiting.2 ], [ %iv_next.2, %loop_exiting.3 ], [ %iv_next.2, %loop_exiting.3 ], [ %iv_next.3, %loop_exiting.4 ], [ %iv_next.3, %loop_exiting.4 ], [ %iv_next.4, %loop_exiting.5 ], [ %iv_next.4, %loop_exiting.5 ], [ %iv_next.5, %loop_exiting.6 ], [ %iv_next.5, %loop_exiting.6 ], [ %iv_next.6, %loop_exiting.7 ], [ %iv_next.6, %loop_exiting.7 ]
; PROLOG-NEXT: br label %exit1
; PROLOG: exit1.loopexit1:
-; PROLOG-NEXT: %ivy.prol = add i64 %iv.prol, %add
; PROLOG-NEXT: br label %exit1
; PROLOG: exit1:
-; PROLOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.prol, %exit1.loopexit1 ]
+; PROLOG-NEXT: %iv.pn.pn = phi i64 [ %iv.pn, %exit1.loopexit ], [ %iv.prol, %exit1.loopexit1 ]
+; PROLOG-NEXT: %result = add i64 %iv.pn.pn, %add
; PROLOG-NEXT: ret i64 %result
; PROLOG: loop_latch.7:
; PROLOG: %iv_next.7 = add nuw nsw i64 %iv, 8
diff --git a/llvm/test/Transforms/PGOProfile/chr.ll b/llvm/test/Transforms/PGOProfile/chr.ll
index e2161d617022..c2e1ae4f53a0 100644
--- a/llvm/test/Transforms/PGOProfile/chr.ll
+++ b/llvm/test/Transforms/PGOProfile/chr.ll
@@ -1649,15 +1649,13 @@ define i32 @test_chr_18(i32* %i, i32 %sum0) !prof !14 {
; CHECK-NEXT: [[SUM1:%.*]] = add i32 [[SUM0:%.*]], 42
; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[LI]], 5
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 5
-; CHECK-NEXT: br i1 [[TMP1]], label [[BB0_SPLIT:%.*]], label [[BB0_SPLIT_NONCHR:%.*]], !prof !15
-; CHECK: bb0.split:
-; CHECK-NEXT: [[INC2:%.*]] = add i32 [[INC1]], 1
+; CHECK-NEXT: br i1 [[TMP1]], label [[BB1:%.*]], label [[BB0_SPLIT_NONCHR:%.*]], !prof !15
+; CHECK: bb1:
; CHECK-NEXT: [[SUM3:%.*]] = add i32 [[SUM0]], 86
; CHECK-NEXT: br label [[BB2]]
; CHECK: bb0.split.nonchr:
; CHECK-NEXT: [[A4_NONCHR:%.*]] = and i32 [[LI]], 4
; CHECK-NEXT: [[CMP4_NONCHR:%.*]] = icmp eq i32 [[A4_NONCHR]], 0
-; CHECK-NEXT: [[INC2_NONCHR:%.*]] = add i32 [[INC1]], 1
; CHECK-NEXT: br i1 [[CMP4_NONCHR]], label [[BB2]], label [[BB1_NONCHR:%.*]], !prof !16
; CHECK: bb1.nonchr:
; CHECK-NEXT: [[A1:%.*]] = and i32 [[LI]], 1
@@ -1666,8 +1664,8 @@ define i32 @test_chr_18(i32* %i, i32 %sum0) !prof !14 {
; CHECK-NEXT: [[SUM3_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], 44
; CHECK-NEXT: br label [[BB2]]
; CHECK: bb2:
-; CHECK-NEXT: [[TMP2]] = phi i32 [ [[INC2]], [[BB0_SPLIT]] ], [ [[INC2_NONCHR]], [[BB1_NONCHR]] ], [ [[INC2_NONCHR]], [[BB0_SPLIT_NONCHR]] ]
-; CHECK-NEXT: [[SUM4:%.*]] = phi i32 [ [[SUM3]], [[BB0_SPLIT]] ], [ [[SUM3_NONCHR]], [[BB1_NONCHR]] ], [ [[SUM1]], [[BB0_SPLIT_NONCHR]] ]
+; CHECK-NEXT: [[SUM4:%.*]] = phi i32 [ [[SUM3]], [[BB1]] ], [ [[SUM1]], [[BB0_SPLIT_NONCHR]] ], [ [[SUM3_NONCHR]], [[BB1_NONCHR]] ]
+; CHECK-NEXT: [[TMP2]] = add i32 [[INC1]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP2]], 100
; CHECK-NEXT: br i1 [[CMP]], label [[BB3:%.*]], label [[BB0]], !prof !16
; CHECK: bb3:
More information about the llvm-commits
mailing list