[llvm] [InstSimplify] Fold `X < Y ? (X + zext(X < Y)) <= Y : false` to `X < Y` (PR #118579)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 3 18:29:11 PST 2024


https://github.com/veera-sivarajan created https://github.com/llvm/llvm-project/pull/118579

This PR simplifies:
`X > Y ? (X + zext(X > Y)) >= Y : false` to `X > Y`
`X < Y ? (X + zext(X < Y)) <= Y : false` to `X < Y`

Proof: https://alive2.llvm.org/ce/z/JFcDzM

This helps improving codegen for Rust's loop over inclusive range with variable upper bound in https://github.com/rust-lang/rust/issues/102462.

>From d2658378b38bceb1ce88ffc570339ee3ae4691b5 Mon Sep 17 00:00:00 2001
From: Veera <sveera.2001 at gmail.com>
Date: Tue, 3 Dec 2024 17:00:06 +0000
Subject: [PATCH 1/2] Add Test

---
 .../InstSimplify/select-icmp-relational.ll    | 472 ++++++++++++++++++
 1 file changed, 472 insertions(+)
 create mode 100644 llvm/test/Transforms/InstSimplify/select-icmp-relational.ll

diff --git a/llvm/test/Transforms/InstSimplify/select-icmp-relational.ll b/llvm/test/Transforms/InstSimplify/select-icmp-relational.ll
new file mode 100644
index 00000000000000..2ec80878e4e9be
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/select-icmp-relational.ll
@@ -0,0 +1,472 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i1 @ult_ule(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ult_ule(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ult i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  %c2 = icmp ule i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ult_ule_no_flags(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ult_ule_no_flags(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ult i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add i8 %x, %z
+  %c2 = icmp ule i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @slt_sle(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @slt_sle(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp slt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp sle i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp slt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nsw i8 %x, %z
+  %c2 = icmp sle i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @slt_sle_no_flags(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @slt_sle_no_flags(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp slt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp sle i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp slt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add i8 %x, %z
+  %c2 = icmp sle i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ugt_uge(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ugt_uge(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ugt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  %c2 = icmp uge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @sgt_sge(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @sgt_sge(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp sge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp sgt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nsw i8 %x, %z
+  %c2 = icmp sge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define <2 x i1> @ult_ule_splat_vector(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @ult_ule_splat_vector(
+; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult <2 x i8> [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i1> [[C1]] to <2 x i8>
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i8> [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule <2 x i8> [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select <2 x i1> [[C1]], <2 x i1> [[C2]], <2 x i1> zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[AND]]
+;
+  %c1 = icmp ult <2 x i8> %x, %y
+  %z = zext <2 x i1> %c1 to <2 x i8>
+  %add = add nuw <2 x i8> %x, %z
+  %c2 = icmp ule <2 x i8> %add, %y
+  %and = select <2 x i1> %c1, <2 x i1> %c2, <2 x i1> <i1 false, i1 false>
+  ret <2 x i1> %and
+}
+
+define <2 x i1> @ult_ule_vector_with_poison(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @ult_ule_vector_with_poison(
+; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult <2 x i8> [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i1> [[C1]] to <2 x i8>
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i8> [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule <2 x i8> [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select <2 x i1> [[C1]], <2 x i1> [[C2]], <2 x i1> <i1 false, i1 poison>
+; CHECK-NEXT:    ret <2 x i1> [[AND]]
+;
+  %c1 = icmp ult <2 x i8> %x, %y
+  %z = zext <2 x i1> %c1 to <2 x i8>
+  %add = add nuw <2 x i8> %x, %z
+  %c2 = icmp ule <2 x i8> %add, %y
+  %and = select <2 x i1> %c1, <2 x i1> %c2, <2 x i1> <i1 false, i1 poison>
+  ret <2 x i1> %and
+}
+
+define i1 @ugt_uge_with_poison(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ugt_uge_with_poison(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    ret i1 false
+;
+  %c1 = icmp ugt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, poison
+  %c2 = icmp uge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+declare void @use(i8)
+declare void @use_bit(i1)
+
+define i1 @ult_ule_multi_use(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ult_ule_multi_use(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
+; CHECK-NEXT:    call void @use_bit(i1 [[C1]])
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    call void @use_bit(i1 [[C2]])
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ult i8 %x, %y
+  call void @use_bit(i1 %c1)
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  %c2 = icmp ule i8 %add, %y
+  call void @use_bit(i1 %c2)
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ult_ule_multi_use_add(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ult_ule_multi_use_add(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    call void @use(i8 [[ADD]])
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ult i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  call void @use(i8 %add)
+  %c2 = icmp ule i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ult_ule_commuted_binop(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ult_ule_commuted_binop(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ult i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %z, %x
+  %c2 = icmp ule i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ult_sext_sub_ule(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ult_sext_sub_ule(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z_NEG:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], [[Z_NEG]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ult i8 %x, %y
+  %z = sext i1 %c1 to i8
+  %add = sub nuw i8 %x, %z
+  %c2 = icmp ule i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ugt_uge_const_fold_false(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ugt_uge_const_fold_false(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ugt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  %c2 = icmp uge i8 %add, %y
+  %c3 = icmp ult i8 10, 1
+  %and = select i1 %c1, i1 %c2, i1 %c3
+  ret i1 %and
+}
+
+define void @rust_inlclusive_noop(i8 noundef %n) unnamed_addr {
+; CHECK-LABEL: define void @rust_inlclusive_noop(
+; CHECK-SAME: i8 noundef [[N:%.*]]) unnamed_addr {
+; CHECK-NEXT:  [[START:.*]]:
+; CHECK-NEXT:    br label %[[BB2_I:.*]]
+; CHECK:       [[BB2_I]]:
+; CHECK-NEXT:    [[ITER_SROA_0_07:%.*]] = phi i8 [ 0, %[[START]] ], [ [[SPEC_SELECT5:%.*]], %[[BB2_I]] ]
+; CHECK-NEXT:    [[_0_I3_I:%.*]] = icmp ult i8 [[ITER_SROA_0_07]], [[N]]
+; CHECK-NEXT:    [[_0_I4_I:%.*]] = zext i1 [[_0_I3_I]] to i8
+; CHECK-NEXT:    [[SPEC_SELECT5]] = add nuw i8 [[ITER_SROA_0_07]], [[_0_I4_I]]
+; CHECK-NEXT:    [[_0_I_NOT_I:%.*]] = icmp ule i8 [[SPEC_SELECT5]], [[N]]
+; CHECK-NEXT:    [[OR_COND_NOT:%.*]] = select i1 [[_0_I3_I]], i1 [[_0_I_NOT_I]], i1 false
+; CHECK-NEXT:    br i1 [[OR_COND_NOT]], label %[[BB2_I]], label %[[THEEND:.*]]
+; CHECK:       [[THEEND]]:
+; CHECK-NEXT:    ret void
+;
+start:
+  br label %bb2.i
+
+bb2.i:
+  %iter.sroa.0.07 = phi i8 [ 0, %start ], [ %spec.select5, %bb2.i ]
+  %_0.i3.i = icmp ult i8 %iter.sroa.0.07, %n
+  %_0.i4.i = zext i1 %_0.i3.i to i8
+  %spec.select5 = add nuw i8 %iter.sroa.0.07, %_0.i4.i
+  %_0.i.not.i = icmp ule i8 %spec.select5, %n
+  %or.cond.not = select i1 %_0.i3.i, i1 %_0.i.not.i, i1 false
+  br i1 %or.cond.not, label %bb2.i, label %theend
+
+theend:
+  ret void
+}
+
+define i1 @ule_ule_negative(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ule_ule_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ule i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ule i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  %c2 = icmp ule i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ugt_ugt_negative(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ugt_ugt_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ugt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  %c2 = icmp ugt i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ugt_sext_sub_uge_negative(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ugt_sext_sub_uge_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z_NEG:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], [[Z_NEG]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ugt i8 %x, %y
+  %z = sext i1 %c1 to i8
+  %add = sub nuw i8 %x, %z
+  %c2 = icmp uge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @false_value_is_true_negative(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @false_value_is_true_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[NOT_C1:%.*]] = xor i1 [[C1]], true
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[NOT_C1]], i1 true, i1 [[C2]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ugt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  %c2 = icmp uge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 true
+  ret i1 %and
+}
+
+define i1 @non_specific_operands_negative(i8 %x, i8 %y, i8 %a, i8 %b) {
+; CHECK-LABEL: define i1 @non_specific_operands_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[A]], [[B]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ult i8 %a, %b
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  %c2 = icmp ule i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @sgt_nuw_sge_negative(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @sgt_nuw_sge_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp sge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp sgt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nuw i8 %x, %z
+  %c2 = icmp sge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ugt_nsw_uge_negative(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ugt_nsw_uge_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ugt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nsw i8 %x, %z
+  %c2 = icmp uge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @non_strict_predicate_negative(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @non_strict_predicate_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp eq i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add nsw i8 %x, %z
+  %c2 = icmp uge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @ugt_uge_no_flags_negative(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ugt_uge_no_flags_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ugt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add i8 %x, %z
+  %c2 = icmp uge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}
+
+define i1 @sgt_sge_no_flags_negative(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @sgt_sge_no_flags_negative(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], [[Z]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp sge i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp sgt i8 %x, %y
+  %z = zext i1 %c1 to i8
+  %add = add i8 %x, %z
+  %c2 = icmp sge i8 %add, %y
+  %and = select i1 %c1, i1 %c2, i1 false
+  ret i1 %and
+}

>From a005baabf62246d6437569940d790b72e4962f28 Mon Sep 17 00:00:00 2001
From: Veera <sveera.2001 at gmail.com>
Date: Wed, 4 Dec 2024 02:19:39 +0000
Subject: [PATCH 2/2] Fold `X < Y ? (X + zext(X < Y)) <= Y : false` to `X < Y`

---
 llvm/lib/Analysis/InstructionSimplify.cpp     | 42 ++++++++++
 .../InstSimplify/select-icmp-relational.ll    | 77 ++++---------------
 2 files changed, 56 insertions(+), 63 deletions(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 01b0a089aab718..8e4731651ea59f 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4639,6 +4639,45 @@ static Value *simplifySelectWithEquivalence(Value *CmpLHS, Value *CmpRHS,
   return nullptr;
 }
 
+/// Simplifies:
+/// `X > Y ? (X + zext(X > Y)) >= Y : false` to `X > Y`
+/// `X < Y ? (X + zext(X < Y)) <= Y : false` to `X < Y`
+static Value *simplifySelectWithStrictICmp(Value *CondVal, Value *TVal,
+                                           Value *FVal,
+                                           const SimplifyQuery &Q) {
+  if (!match(FVal, m_Zero()))
+    return nullptr;
+
+  ICmpInst::Predicate Pred;
+  Value *CmpLHS, *CmpRHS;
+
+  if (!match(CondVal, m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS))))
+    return nullptr;
+
+  if (!CmpInst::isStrictPredicate(Pred))
+    return nullptr;
+
+  ICmpInst::Predicate NonStrictPred = ICmpInst::getNonStrictPredicate(Pred);
+  BinaryOperator *BinOp;
+
+  if (!match(TVal,
+             m_SpecificICmp(NonStrictPred, m_BinOp(BinOp), m_Specific(CmpRHS))))
+    return nullptr;
+
+  // This fold works for GT only when it does not wrap.
+  if (Pred == ICmpInst::ICMP_UGT && !Q.IIQ.hasNoUnsignedWrap(BinOp))
+    return nullptr;
+
+  if (Pred == ICmpInst::ICMP_SGT && !Q.IIQ.hasNoSignedWrap(BinOp))
+    return nullptr;
+
+  if (!match(BinOp, m_c_BinOp(Instruction::Add, m_Specific(CmpLHS),
+                              m_ZExt(m_Specific(CondVal)))))
+    return nullptr;
+
+  return CondVal;
+}
+
 /// Try to simplify a select instruction when its condition operand is an
 /// integer comparison.
 static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
@@ -4761,6 +4800,9 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
     }
   }
 
+  if (Value *V = simplifySelectWithStrictICmp(CondVal, TrueVal, FalseVal, Q))
+    return V;
+
   return nullptr;
 }
 
diff --git a/llvm/test/Transforms/InstSimplify/select-icmp-relational.ll b/llvm/test/Transforms/InstSimplify/select-icmp-relational.ll
index 2ec80878e4e9be..c2f120469c6b59 100644
--- a/llvm/test/Transforms/InstSimplify/select-icmp-relational.ll
+++ b/llvm/test/Transforms/InstSimplify/select-icmp-relational.ll
@@ -5,11 +5,7 @@ define i1 @ult_ule(i8 %x, i8 %y) {
 ; CHECK-LABEL: define i1 @ult_ule(
 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp ult i8 %x, %y
   %z = zext i1 %c1 to i8
@@ -23,11 +19,7 @@ define i1 @ult_ule_no_flags(i8 %x, i8 %y) {
 ; CHECK-LABEL: define i1 @ult_ule_no_flags(
 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
-; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp ult i8 %x, %y
   %z = zext i1 %c1 to i8
@@ -41,11 +33,7 @@ define i1 @slt_sle(i8 %x, i8 %y) {
 ; CHECK-LABEL: define i1 @slt_sle(
 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp slt i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp sle i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp slt i8 %x, %y
   %z = zext i1 %c1 to i8
@@ -59,11 +47,7 @@ define i1 @slt_sle_no_flags(i8 %x, i8 %y) {
 ; CHECK-LABEL: define i1 @slt_sle_no_flags(
 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp slt i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
-; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp sle i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp slt i8 %x, %y
   %z = zext i1 %c1 to i8
@@ -77,11 +61,7 @@ define i1 @ugt_uge(i8 %x, i8 %y) {
 ; CHECK-LABEL: define i1 @ugt_uge(
 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp ugt i8 %x, %y
   %z = zext i1 %c1 to i8
@@ -95,11 +75,7 @@ define i1 @sgt_sge(i8 %x, i8 %y) {
 ; CHECK-LABEL: define i1 @sgt_sge(
 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp sge i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp sgt i8 %x, %y
   %z = zext i1 %c1 to i8
@@ -113,11 +89,7 @@ define <2 x i1> @ult_ule_splat_vector(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: define <2 x i1> @ult_ule_splat_vector(
 ; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ult <2 x i8> [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i1> [[C1]] to <2 x i8>
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i8> [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp ule <2 x i8> [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select <2 x i1> [[C1]], <2 x i1> [[C2]], <2 x i1> zeroinitializer
-; CHECK-NEXT:    ret <2 x i1> [[AND]]
+; CHECK-NEXT:    ret <2 x i1> [[C1]]
 ;
   %c1 = icmp ult <2 x i8> %x, %y
   %z = zext <2 x i1> %c1 to <2 x i8>
@@ -131,11 +103,7 @@ define <2 x i1> @ult_ule_vector_with_poison(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: define <2 x i1> @ult_ule_vector_with_poison(
 ; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ult <2 x i8> [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i1> [[C1]] to <2 x i8>
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i8> [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp ule <2 x i8> [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select <2 x i1> [[C1]], <2 x i1> [[C2]], <2 x i1> <i1 false, i1 poison>
-; CHECK-NEXT:    ret <2 x i1> [[AND]]
+; CHECK-NEXT:    ret <2 x i1> [[C1]]
 ;
   %c1 = icmp ult <2 x i8> %x, %y
   %z = zext <2 x i1> %c1 to <2 x i8>
@@ -170,8 +138,7 @@ define i1 @ult_ule_multi_use(i8 %x, i8 %y) {
 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
 ; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
 ; CHECK-NEXT:    call void @use_bit(i1 [[C2]])
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp ult i8 %x, %y
   call void @use_bit(i1 %c1)
@@ -190,9 +157,7 @@ define i1 @ult_ule_multi_use_add(i8 %x, i8 %y) {
 ; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
 ; CHECK-NEXT:    call void @use(i8 [[ADD]])
-; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp ult i8 %x, %y
   %z = zext i1 %c1 to i8
@@ -207,11 +172,7 @@ define i1 @ult_ule_commuted_binop(i8 %x, i8 %y) {
 ; CHECK-LABEL: define i1 @ult_ule_commuted_binop(
 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp ult i8 %x, %y
   %z = zext i1 %c1 to i8
@@ -225,11 +186,7 @@ define i1 @ult_sext_sub_ule(i8 %x, i8 %y) {
 ; CHECK-LABEL: define i1 @ult_sext_sub_ule(
 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[Z_NEG:%.*]] = zext i1 [[C1]] to i8
-; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], [[Z_NEG]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp ult i8 %x, %y
   %z = sext i1 %c1 to i8
@@ -243,11 +200,7 @@ define i1 @ugt_uge_const_fold_false(i8 %x, i8 %y) {
 ; CHECK-LABEL: define i1 @ugt_uge_const_fold_false(
 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[C1]] to i8
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], [[Z]]
-; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[ADD]], [[Y]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp ugt i8 %x, %y
   %z = zext i1 %c1 to i8
@@ -268,9 +221,7 @@ define void @rust_inlclusive_noop(i8 noundef %n) unnamed_addr {
 ; CHECK-NEXT:    [[_0_I3_I:%.*]] = icmp ult i8 [[ITER_SROA_0_07]], [[N]]
 ; CHECK-NEXT:    [[_0_I4_I:%.*]] = zext i1 [[_0_I3_I]] to i8
 ; CHECK-NEXT:    [[SPEC_SELECT5]] = add nuw i8 [[ITER_SROA_0_07]], [[_0_I4_I]]
-; CHECK-NEXT:    [[_0_I_NOT_I:%.*]] = icmp ule i8 [[SPEC_SELECT5]], [[N]]
-; CHECK-NEXT:    [[OR_COND_NOT:%.*]] = select i1 [[_0_I3_I]], i1 [[_0_I_NOT_I]], i1 false
-; CHECK-NEXT:    br i1 [[OR_COND_NOT]], label %[[BB2_I]], label %[[THEEND:.*]]
+; CHECK-NEXT:    br i1 [[_0_I3_I]], label %[[BB2_I]], label %[[THEEND:.*]]
 ; CHECK:       [[THEEND]]:
 ; CHECK-NEXT:    ret void
 ;



More information about the llvm-commits mailing list