diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index c265516213aa4..16efe863779a3 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -345,10 +345,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, return false; // Get the constant out of the ICmp, if there is one. + // Only try this when exactly 1 operand is a constant (if both operands + // are constant, the icmp should eventually simplify). Otherwise, we may + // invert the transform that reduces set bits and infinite-loop. + Value *X; const APInt *CmpC; ICmpInst::Predicate Pred; - if (!match(I->getOperand(0), m_c_ICmp(Pred, m_APInt(CmpC), m_Value())) || - CmpC->getBitWidth() != SelC->getBitWidth()) + if (!match(I->getOperand(0), m_ICmp(Pred, m_Value(X), m_APInt(CmpC))) || + isa(X) || CmpC->getBitWidth() != SelC->getBitWidth()) return ShrinkDemandedConstant(I, OpNo, DemandedMask); // If the constant is already the same as the ICmp, leave it as-is. diff --git a/llvm/test/Transforms/InstCombine/select-imm-canon.ll b/llvm/test/Transforms/InstCombine/select-imm-canon.ll index e230b3b927774..fec6d693954a1 100644 --- a/llvm/test/Transforms/InstCombine/select-imm-canon.ll +++ b/llvm/test/Transforms/InstCombine/select-imm-canon.ll @@ -87,3 +87,41 @@ define i8 @original_logical(i32 %A, i32 %B) { %conv7 = trunc i32 %spec.select.i to i8 ret i8 %conv7 } + +; This would infinite loop because we have potentially opposing +; constant transforms on degenerate (unsimplified) cmps. + +define i32 @PR49205(i32 %t0, i1 %b) { +; CHECK-LABEL: @PR49205( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: br i1 [[B:%.*]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: br label [[FOR_COND]] +; CHECK: for.end: +; CHECK-NEXT: ret i32 1 +; +entry: + br label %for.cond + +for.cond: + %s = phi i32 [ 7, %entry ], [ %add, %for.body ] + br i1 %b, label %for.body, label %for.end + +for.body: + %div = add i32 %t0, undef + %add = add nsw i32 %div, 1 + br label %for.cond + +for.end: + %cmp6 = icmp ne i32 %s, 4 + %conv = zext i1 %cmp6 to i32 + %and7 = and i32 %s, %conv + %sub = sub i32 %s, %and7 + %cmp9 = icmp ne i32 %sub, 4 + %conv10 = zext i1 %cmp9 to i32 + %sub11 = sub i32 %conv10, %sub + %and = and i32 %sub11, 1 + ret i32 %and +}