Skip to content

[InstCombine] Fold correlated poison-blocking logical selects - #221130

Open
JihyeonJeong129 wants to merge 2 commits into
llvm:mainfrom
JihyeonJeong129:instcombine-correlated-poison-select-fold
Open

[InstCombine] Fold correlated poison-blocking logical selects#221130
JihyeonJeong129 wants to merge 2 commits into
llvm:mainfrom
JihyeonJeong129:instcombine-correlated-poison-select-fold

Conversation

@JihyeonJeong129

Copy link
Copy Markdown

This patch folds correlated poison-blocking logical select conditions of the following form:

C = select A, B, false
G = select !A, true, B
select G, (select C, T, F), X
  -> select A, (select B, T, X), F

The transformation is implemented as part of foldNestedSelects() and uses its existing profitability rule to avoid increasing the instruction count.

Tests cover:

  • The canonical scalar poison-blocking pattern
  • A non-canonical guard normalized by foldSelectOfBools()
  • Fixed-width vector conditions
  • An inner mux with multiple uses
  • The negative case where both the guard and inner mux have multiple uses
  • Bitwise and and or conditions excluded from the fold
  • Swapped poison-blocking AND and OR operands
  • A vector NOT mask containing a poison lane
  • Preservation of outer fast-math flags without propagating inner flags

Testing:

llvm/test/Transforms/InstCombine/select-correlated-poison-blocking.ll
ninja -C build check-llvm

Fixes #198820

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Hello @JihyeonJeong129 👋

Thank you for submitting a Pull Request (PR) to the LLVM Project. Since this is your first PR, here are a few useful links covering our main contribution policies and review practices.

  • All contributions to LLVM must follow our LLVM AI Tool Use Policy. In particular, if you used AI while working on this PR, remember to add a note to the PR description.
  • The LLVM Code-Review Policy and Practices document contains practical information about the PR process, including how patches are reviewed and accepted, and who can review a PR.
  • Our LLVM Developer Policy describes our expectations for code quality, commit summaries and contains notes on our CI system.
  • The InstCombine Contributor Guide lays out a series of rules that contributions to InstCombine (and other middle-end components) should follow.

Please reply to this message to confirm that you have read these policies, especially the LLVM AI Tool Use Policy, and that any AI tool usage has been noted in the PR description.


Frequently asked questions

How do I add reviewers?

This PR will be automatically labeled, and the relevant teams will be notified. For some parts of the project, reviewers may also be added automatically.

You can also add reviewers manually using the Reviewers section on this page. If you cannot use that section, it is probably because you do not have write permissions for the repository. In that case, you can request a review by tagging reviewers in a comment using @ followed by their GitHub username.

What if there are no comments?

If you have not received any comments on your PR after a week, you can request a review by pinging the PR with a comment such as “Ping”. The common courtesy ping rate is once a week. Please remember that you are asking for volunteer time from other developers.

Are any special GitHub settings required to contribute to LLVM?

We only require contributors to have a public email address associated with their GitHub commits, see this section of LLVM Developer Policy for details.


If you have questions, feel free to leave a comment on this PR, or ask on LLVM Discord or LLVM Discourse.

Thank you,
The LLVM Community

@llvmorg-github-actions llvmorg-github-actions Bot added llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms labels Sep 4, 2026
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-llvm-transforms

Author: Jeong Jihyeon (JihyeonJeong129)

Changes

This patch folds correlated poison-blocking logical select conditions of the following form:

C = select A, B, false
G = select !A, true, B
select G, (select C, T, F), X
  -> select A, (select B, T, X), F

The transformation is implemented as part of foldNestedSelects() and uses its existing profitability rule to avoid increasing the instruction count.

Tests cover:

  • The canonical scalar poison-blocking pattern
  • A non-canonical guard normalized by foldSelectOfBools()
  • Fixed-width vector conditions
  • An inner mux with multiple uses
  • The negative case where both the guard and inner mux have multiple uses
  • Bitwise and and or conditions excluded from the fold
  • Swapped poison-blocking AND and OR operands
  • A vector NOT mask containing a poison lane
  • Preservation of outer fast-math flags without propagating inner flags

Testing:

llvm/test/Transforms/InstCombine/select-correlated-poison-blocking.ll
ninja -C build check-llvm

Fixes #198820


Full diff: https://github.com/llvm/llvm-project/pull/221130.diff

3 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+32)
  • (modified) llvm/test/Transforms/InstCombine/nested-select.ll (+208)
  • (modified) llvm/test/Transforms/InstCombine/preserve-profile.ll (+15)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 81d949fd1fb28..8732f3c5c01eb 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3626,6 +3626,11 @@ foldSelectOfSymmetricSelect(SelectInst &OuterSelVal,
 /// and rewrite it as
 ///   %inner.sel = select i1 %cond.alternative, i8 %sel.outer.t, i8 %sel.inner.t
 ///   %sel.outer = select i1 %cond.inner, i8 %inner.sel, i8 %sel.inner.f
+///
+/// Also fold correlated poison-blocking conditions
+///   select (!A || B), (select (A && B), T, F), X
+/// into
+///   select A, (select B, T, X), F
 static Instruction *foldNestedSelects(SelectInst &OuterSelVal,
                                       InstCombiner::BuilderTy &Builder) {
   // We must start with a `select`.
@@ -3662,6 +3667,33 @@ static Instruction *foldNestedSelects(SelectInst &OuterSelVal,
   if (match(InnerSel.Cond, m_Not(m_Value(InnerSel.Cond))))
     std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
 
+  // Fold correlated poison-blocking logical selects:
+  //   C = A && B
+  //   G = !A || B
+  //   select G, (select C, T, F), X
+  //     --> select A, (select B, T, X), F
+  // Only the canonical poison-blocking select forms with this exact operand
+  // order are handled. Bitwise and/or, commuted operands and a 'not' with
+  // poison lanes may also be valid, but they have not been verified yet.
+  if (!IsAndVariant && isa<SelectInst>(OuterSel.Cond) &&
+      isa<SelectInst>(InnerSel.Cond)) {
+    Value *A, *B;
+    if (match(OuterSel.Cond,
+              m_LogicalOr(m_NotForbidPoison(m_Value(A)), m_Value(B))) &&
+        match(InnerSel.Cond, m_LogicalAnd(m_Specific(A), m_Specific(B)))) {
+      Value *NewInner = Builder.CreateSelectWithUnknownProfile(
+          B, InnerSel.TrueVal, OuterSel.FalseVal, DEBUG_TYPE);
+      NewInner->takeName(InnerSelVal);
+
+      auto *NewOuter = SelectInst::Create(A, NewInner, InnerSel.FalseVal);
+      setExplicitlyUnknownBranchWeightsIfProfiled(*NewOuter, DEBUG_TYPE,
+                                                  OuterSelVal.getFunction());
+      if (auto *FPOp = dyn_cast<FPMathOperator>(&OuterSelVal))
+        NewOuter->setFastMathFlags(FPOp->getFastMathFlags());
+      return NewOuter;
+    }
+  }
+
   Value *AltCond = nullptr;
   auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](auto m_InnerCond) {
     // An unsimplified select condition can match both LogicalAnd and LogicalOr
diff --git a/llvm/test/Transforms/InstCombine/nested-select.ll b/llvm/test/Transforms/InstCombine/nested-select.ll
index b8a7d4e8ab789..db4aefda6c753 100644
--- a/llvm/test/Transforms/InstCombine/nested-select.ll
+++ b/llvm/test/Transforms/InstCombine/nested-select.ll
@@ -29,6 +29,214 @@ define i8 @orcond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner
   ret i8 %outer.sel
 }
 
+; Correlated poison-blocking logical conditions
+
+define i8 @correlated_poison_blocking_conditions(i1 %a, i1 %b, i8 %t, i8 %f, i8 %x) {
+; CHECK-LABEL: @correlated_poison_blocking_conditions(
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[B:%.*]], i8 [[T:%.*]], i8 [[X:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[A:%.*]], i8 [[MUX]], i8 [[F:%.*]]
+; CHECK-NEXT:    ret i8 [[RET]]
+;
+  %and = select i1 %a, i1 %b, i1 false
+  %not.a = xor i1 %a, true
+  %guard = select i1 %not.a, i1 true, i1 %b
+  %mux = select i1 %and, i8 %t, i8 %f
+  %ret = select i1 %guard, i8 %mux, i8 %x
+  ret i8 %ret
+}
+
+; Verify that foldSelectOfBools canonicalizes the guard before this fold.
+
+define i8 @correlated_poison_blocking_conditions_noncanonical_guard(i1 %a, i1 %b, i8 %t, i8 %f, i8 %x) {
+; CHECK-LABEL: @correlated_poison_blocking_conditions_noncanonical_guard(
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[B:%.*]], i8 [[T:%.*]], i8 [[X:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[A:%.*]], i8 [[MUX]], i8 [[F:%.*]]
+; CHECK-NEXT:    ret i8 [[RET]]
+;
+  %and = select i1 %a, i1 %b, i1 false
+  %guard = select i1 %a, i1 %b, i1 true
+  %mux = select i1 %and, i8 %t, i8 %f
+  %ret = select i1 %guard, i8 %mux, i8 %x
+  ret i8 %ret
+}
+
+define <2 x i8> @correlated_poison_blocking_conditions_vec(<2 x i1> %a, <2 x i1> %b, <2 x i8> %t, <2 x i8> %f, <2 x i8> %x) {
+; CHECK-LABEL: @correlated_poison_blocking_conditions_vec(
+; CHECK-NEXT:    [[MUX:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> [[T:%.*]], <2 x i8> [[X:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select <2 x i1> [[A:%.*]], <2 x i8> [[MUX]], <2 x i8> [[F:%.*]]
+; CHECK-NEXT:    ret <2 x i8> [[RET]]
+;
+  %and = select <2 x i1> %a, <2 x i1> %b, <2 x i1> zeroinitializer
+  %not.a = xor <2 x i1> %a, <i1 true, i1 true>
+  %guard = select <2 x i1> %not.a, <2 x i1> <i1 true, i1 true>, <2 x i1> %b
+  %mux = select <2 x i1> %and, <2 x i8> %t, <2 x i8> %f
+  %ret = select <2 x i1> %guard, <2 x i8> %mux, <2 x i8> %x
+  ret <2 x i8> %ret
+}
+
+; The existing profitability rule permits reassociation when the guard is
+; one-use, even if the inner mux has another use.
+
+define i8 @correlated_poison_blocking_conditions_mux_multiuse(i1 %a, i1 %b, i8 %t, i8 %f, i8 %x) {
+; CHECK-LABEL: @correlated_poison_blocking_conditions_mux_multiuse(
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT:    [[OLD_MUX:%.*]] = select i1 [[AND]], i8 [[T:%.*]], i8 [[F:%.*]]
+; CHECK-NEXT:    call void @use.i8(i8 [[OLD_MUX]])
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[B]], i8 [[T]], i8 [[X:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[A]], i8 [[MUX]], i8 [[F]]
+; CHECK-NEXT:    ret i8 [[RET]]
+;
+  %and = select i1 %a, i1 %b, i1 false
+  %not.a = xor i1 %a, true
+  %guard = select i1 %not.a, i1 true, i1 %b
+  %mux = select i1 %and, i8 %t, i8 %f
+  call void @use.i8(i8 %mux)
+  %ret = select i1 %guard, i8 %mux, i8 %x
+  ret i8 %ret
+}
+
+; Do not increase instruction count when neither the guard nor the mux is
+; one-use.
+
+define i8 @correlated_poison_blocking_conditions_both_multiuse(i1 %a, i1 %b, i8 %t, i8 %f, i8 %x) {
+; CHECK-LABEL: @correlated_poison_blocking_conditions_both_multiuse(
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A]], true
+; CHECK-NEXT:    [[GUARD:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B]]
+; CHECK-NEXT:    call void @use.i1(i1 [[GUARD]])
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[AND]], i8 [[T:%.*]], i8 [[F:%.*]]
+; CHECK-NEXT:    call void @use.i8(i8 [[MUX]])
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[GUARD]], i8 [[MUX]], i8 [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[RET]]
+;
+  %and = select i1 %a, i1 %b, i1 false
+  %not.a = xor i1 %a, true
+  %guard = select i1 %not.a, i1 true, i1 %b
+  call void @use.i1(i1 %guard)
+  %mux = select i1 %and, i8 %t, i8 %f
+  call void @use.i8(i8 %mux)
+  %ret = select i1 %guard, i8 %mux, i8 %x
+  ret i8 %ret
+}
+
+; Bitwise or is not handled yet. It may also be valid, but it has not been
+; verified.
+
+define i8 @correlated_conditions_bitwise_or(i1 %a, i8 %b8, i8 %t, i8 %f, i8 %x) {
+; CHECK-LABEL: @correlated_conditions_bitwise_or(
+; CHECK-NEXT:    [[B:%.*]] = trunc i8 [[B8:%.*]] to i1
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B]], i1 false
+; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A]], true
+; CHECK-NEXT:    [[GUARD:%.*]] = or i1 [[NOT_A]], [[B]]
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[AND]], i8 [[T:%.*]], i8 [[F:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[GUARD]], i8 [[MUX]], i8 [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[RET]]
+;
+  %b = trunc i8 %b8 to i1
+  %and = select i1 %a, i1 %b, i1 false
+  %not.a = xor i1 %a, true
+  %guard = or i1 %not.a, %b
+  %mux = select i1 %and, i8 %t, i8 %f
+  %ret = select i1 %guard, i8 %mux, i8 %x
+  ret i8 %ret
+}
+
+; Bitwise and is not handled yet. It may also be valid, but it has not been
+; verified.
+
+define i8 @correlated_conditions_bitwise_and(i1 %a, i8 %b8, i8 %t, i8 %f, i8 %x) {
+; CHECK-LABEL: @correlated_conditions_bitwise_and(
+; CHECK-NEXT:    [[B:%.*]] = trunc i8 [[B8:%.*]] to i1
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[A:%.*]], [[B]]
+; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A]], true
+; CHECK-NEXT:    [[GUARD:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B]]
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[AND]], i8 [[T:%.*]], i8 [[F:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[GUARD]], i8 [[MUX]], i8 [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[RET]]
+;
+  %b = trunc i8 %b8 to i1
+  %and = and i1 %a, %b
+  %not.a = xor i1 %a, true
+  %guard = select i1 %not.a, i1 true, i1 %b
+  %mux = select i1 %and, i8 %t, i8 %f
+  %ret = select i1 %guard, i8 %mux, i8 %x
+  ret i8 %ret
+}
+
+; Commuted AND operands are not handled yet. They may also be valid, but this
+; has not been verified.
+
+define i8 @correlated_conditions_swapped_and(i1 %a, i1 %b, i8 %t, i8 %f, i8 %x) {
+; CHECK-LABEL: @correlated_conditions_swapped_and(
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
+; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A]], true
+; CHECK-NEXT:    [[GUARD:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B]]
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[AND]], i8 [[T:%.*]], i8 [[F:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[GUARD]], i8 [[MUX]], i8 [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[RET]]
+;
+  %and = select i1 %b, i1 %a, i1 false
+  %not.a = xor i1 %a, true
+  %guard = select i1 %not.a, i1 true, i1 %b
+  %mux = select i1 %and, i8 %t, i8 %f
+  %ret = select i1 %guard, i8 %mux, i8 %x
+  ret i8 %ret
+}
+
+; Commuted OR operands are not handled yet. They may also be valid, but this
+; has not been verified.
+
+define i8 @correlated_conditions_swapped_or(i1 %a, i1 %b, i8 %t, i8 %f, i8 %x) {
+; CHECK-LABEL: @correlated_conditions_swapped_or(
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A]], true
+; CHECK-NEXT:    [[GUARD:%.*]] = select i1 [[B]], i1 true, i1 [[NOT_A]]
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[AND]], i8 [[T:%.*]], i8 [[F:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[GUARD]], i8 [[MUX]], i8 [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[RET]]
+;
+  %and = select i1 %a, i1 %b, i1 false
+  %not.a = xor i1 %a, true
+  %guard = select i1 %b, i1 true, i1 %not.a
+  %mux = select i1 %and, i8 %t, i8 %f
+  %ret = select i1 %guard, i8 %mux, i8 %x
+  ret i8 %ret
+}
+
+; A 'not' with a poison lane is not handled yet (m_NotForbidPoison). It may
+; also be valid, but it has not been verified.
+
+define <2 x i8> @correlated_conditions_poison_in_not(<2 x i1> %a, <2 x i1> %b, <2 x i8> %t, <2 x i8> %f, <2 x i8> %x) {
+; CHECK-LABEL: @correlated_conditions_poison_in_not(
+; CHECK-NEXT:    [[AND:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
+; CHECK-NEXT:    [[NOT_A:%.*]] = xor <2 x i1> [[A]], <i1 true, i1 poison>
+; CHECK-NEXT:    [[GUARD:%.*]] = select <2 x i1> [[NOT_A]], <2 x i1> splat (i1 true), <2 x i1> [[B]]
+; CHECK-NEXT:    [[MUX:%.*]] = select <2 x i1> [[AND]], <2 x i8> [[T:%.*]], <2 x i8> [[F:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select <2 x i1> [[GUARD]], <2 x i8> [[MUX]], <2 x i8> [[X:%.*]]
+; CHECK-NEXT:    ret <2 x i8> [[RET]]
+;
+  %and = select <2 x i1> %a, <2 x i1> %b, <2 x i1> zeroinitializer
+  %not.a = xor <2 x i1> %a, <i1 true, i1 poison>
+  %guard = select <2 x i1> %not.a, <2 x i1> <i1 true, i1 true>, <2 x i1> %b
+  %mux = select <2 x i1> %and, <2 x i8> %t, <2 x i8> %f
+  %ret = select <2 x i1> %guard, <2 x i8> %mux, <2 x i8> %x
+  ret <2 x i8> %ret
+}
+
+define float @correlated_poison_blocking_conditions_fmf(i1 %a, i1 %b, float %t, float %f, float %x) {
+; CHECK-LABEL: @correlated_poison_blocking_conditions_fmf(
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[B:%.*]], float [[T:%.*]], float [[X:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = select nnan i1 [[A:%.*]], float [[MUX]], float [[F:%.*]]
+; CHECK-NEXT:    ret float [[RET]]
+;
+  %and = select i1 %a, i1 %b, i1 false
+  %not.a = xor i1 %a, true
+  %guard = select i1 %not.a, i1 true, i1 %b
+  %mux = select ninf i1 %and, float %t, float %f
+  %ret = select nnan i1 %guard, float %mux, float %x
+  ret float %ret
+}
+
 ; Extra use tests (basic test, no inversions)
 
 define i8 @andcond.extrause0(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) {
diff --git a/llvm/test/Transforms/InstCombine/preserve-profile.ll b/llvm/test/Transforms/InstCombine/preserve-profile.ll
index 8cb3e685ae302..3cb8f9669f8cc 100644
--- a/llvm/test/Transforms/InstCombine/preserve-profile.ll
+++ b/llvm/test/Transforms/InstCombine/preserve-profile.ll
@@ -83,6 +83,21 @@ define i32 @add_zext_zext_i1(i1 %a) !prof !0 {
   ret i32 %add
 }
 
+define i32 @correlated_poison_blocking_selects(i1 %a, i1 %b, i32 %t, i32 %f, i32 %x) !prof !0 {
+; CHECK-LABEL: define i32 @correlated_poison_blocking_selects(
+; CHECK-SAME: i1 [[A:%.*]], i1 [[B:%.*]], i32 [[T:%.*]], i32 [[F:%.*]], i32 [[X:%.*]]) !prof [[PROF0]] {
+; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[B]], i32 [[T]], i32 [[X]], !prof [[PROF2]]
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[A]], i32 [[MUX]], i32 [[F]], !prof [[PROF2]]
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %and = select i1 %a, i1 %b, i1 false
+  %not.a = xor i1 %a, true
+  %guard = select i1 %not.a, i1 true, i1 %b
+  %mux = select i1 %and, i32 %t, i32 %f, !prof !1
+  %ret = select i1 %guard, i32 %mux, i32 %x, !prof !1
+  ret i32 %ret
+}
+
 define i32 @no_count_no_branch_weights(i1 %a) {
 ; CHECK-LABEL: define i32 @no_count_no_branch_weights(
 ; CHECK-SAME: i1 [[A:%.*]]) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[InstCombine/SimplifyCFG] Missed simplification for correlated poison-blocking select conditions

1 participant