diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 9bd49f76d4bd5..71c2d68881441 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2891,8 +2891,15 @@ static Instruction *foldNestedSelects(SelectInst &OuterSelVal, std::swap(InnerSel.TrueVal, InnerSel.FalseVal); Value *AltCond = nullptr; - auto matchOuterCond = [OuterSel, &AltCond](auto m_InnerCond) { - return match(OuterSel.Cond, m_c_LogicalOp(m_InnerCond, m_Value(AltCond))); + auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](auto m_InnerCond) { + // An unsimplified select condition can match both LogicalAnd and LogicalOr + // (select true, true, false). Since below we assume that LogicalAnd implies + // InnerSel match the FVal and vice versa for LogicalOr, we can't match the + // alternative pattern here. + return IsAndVariant ? match(OuterSel.Cond, + m_c_LogicalAnd(m_InnerCond, m_Value(AltCond))) + : match(OuterSel.Cond, + m_c_LogicalOr(m_InnerCond, m_Value(AltCond))); }; // Finally, match the condition that was driving the outermost `select`, diff --git a/llvm/test/Transforms/InstCombine/pr71330.ll b/llvm/test/Transforms/InstCombine/pr71330.ll index 1620142523f75..8eb98b2f6436b 100644 --- a/llvm/test/Transforms/InstCombine/pr71330.ll +++ b/llvm/test/Transforms/InstCombine/pr71330.ll @@ -15,8 +15,7 @@ define void @pr71330(i32 %conv, i1 %tobool19.not4, i16 %lb) { ; CHECK: for.cond7.preheader.split.us.split: ; CHECK-NEXT: ret void ; CHECK: for.cond7: -; CHECK-NEXT: [[ADD9:%.*]] = add i32 [[CONV]], 3 -; CHECK-NEXT: [[CMP12:%.*]] = icmp slt i32 [[ADD9]], 0 +; CHECK-NEXT: [[CMP12:%.*]] = icmp slt i32 [[CONV]], 0 ; CHECK-NEXT: br i1 [[CMP12]], label [[FOR_BODY14:%.*]], label [[FOR_END25]] ; CHECK: for.body14: ; CHECK-NEXT: ret void