diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2773,6 +2773,21 @@ if (Res && *Res == false) return replaceOperand(SI, 1, A); } + // select c, true, (select a, b, false) -> select c, true, a + // select (select a, b, false), true, c -> select a, true, c + // if c = false implies that b = true + if (match(TrueVal, m_One()) && + match(FalseVal, m_Select(m_Value(A), m_Value(B), m_Zero()))) { + Optional Res = isImpliedCondition(CondVal, B, DL, false); + if (Res && *Res == true) + return replaceOperand(SI, 2, A); + } + if (match(CondVal, m_Select(m_Value(A), m_Value(B), m_Zero())) && + match(TrueVal, m_One())) { + Optional Res = isImpliedCondition(FalseVal, B, DL, false); + if (Res && *Res == true) + return replaceOperand(SI, 0, A); + } // sel (sel c, a, false), true, (sel !c, b, false) -> sel c, a, b // sel (sel !c, a, false), true, (sel c, b, false) -> sel c, b, a diff --git a/llvm/test/Transforms/InstCombine/select-safe-transforms.ll b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll --- a/llvm/test/Transforms/InstCombine/select-safe-transforms.ll +++ b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll @@ -181,10 +181,8 @@ define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i1 %y) { ; CHECK-LABEL: @orn_and_cmp_1_logical( -; CHECK-NEXT: [[X:%.*]] = icmp sgt i37 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A]], [[B]] -; CHECK-NEXT: [[AND:%.*]] = select i1 [[Y:%.*]], i1 [[X]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[AND]] +; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y:%.*]] ; CHECK-NEXT: ret i1 [[OR]] ; %x = icmp sgt i37 %a, %b @@ -196,10 +194,8 @@ define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i1 %y) { ; CHECK-LABEL: @orn_and_cmp_2_logical( -; CHECK-NEXT: [[X:%.*]] = icmp sge i16 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A]], [[B]] -; CHECK-NEXT: [[AND:%.*]] = select i1 [[Y:%.*]], i1 [[X]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AND]], i1 true, i1 [[X_INV]] +; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[X_INV]] ; CHECK-NEXT: ret i1 [[OR]] ; %x = icmp sge i16 %a, %b