Index: lib/Transforms/Scalar/GuardWidening.cpp =================================================================== --- lib/Transforms/Scalar/GuardWidening.cpp +++ lib/Transforms/Scalar/GuardWidening.cpp @@ -344,6 +344,15 @@ Instruction *GuardInst, const df_iterator &DFSI, const DenseMap> & GuardsInBlock, bool InvertCondition) { + auto *Cond = getCondition(GuardInst); + auto *True = ConstantInt::getTrue(GuardInst->getContext()); + auto *False = ConstantInt::getFalse(GuardInst->getContext()); + // Ignore trivial true or false conditions. These instructions will be + // trivially eliminated by any cleanup pass. Do not erase them because other + // guards can possibly be widened into them. + if (Cond == True || Cond == False) + return false; + Instruction *BestSoFar = nullptr; auto BestScoreSoFar = WS_IllegalOrNegative; auto *GuardInstLoop = LI.getLoopFor(GuardInst->getParent()); @@ -388,7 +397,7 @@ for (auto *Candidate : make_range(I, E)) { auto Score = computeWideningScore(GuardInst, GuardInstLoop, Candidate, CurLoop); - LLVM_DEBUG(dbgs() << "Score between " << *getCondition(GuardInst) + LLVM_DEBUG(dbgs() << "Score between " << *Cond << " and " << *getCondition(Candidate) << " is " << scoreTypeToString(Score) << "\n"); if (Score > BestScoreSoFar) { @@ -410,9 +419,7 @@ << " with score " << scoreTypeToString(BestScoreSoFar) << "\n"); widenGuard(BestSoFar, getCondition(GuardInst), InvertCondition); - auto NewGuardCondition = InvertCondition - ? ConstantInt::getFalse(GuardInst->getContext()) - : ConstantInt::getTrue(GuardInst->getContext()); + auto *NewGuardCondition = InvertCondition ? False : True; setCondition(GuardInst, NewGuardCondition); EliminatedGuardsAndBranches.push_back(GuardInst); WidenedGuards.insert(BestSoFar); Index: test/Transforms/GuardWidening/basic.ll =================================================================== --- test/Transforms/GuardWidening/basic.ll +++ test/Transforms/GuardWidening/basic.ll @@ -379,3 +379,29 @@ right: ret void } + +; Make sure we do not widen guard by trivial true conditions into something. +define void @f_15(i1 %cond_0, i1 %cond_1) { +; CHECK-LABEL: @f_15( +entry: +; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] +; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] +; CHECK: ret void + + call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] + ret void +} + +; Make sure we do not widen guard by trivial false conditions into something. +define void @f_16(i1 %cond_0, i1 %cond_1) { +; CHECK-LABEL: @f_16( +entry: +; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] +; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] +; CHECK: ret void + + call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] + ret void +}