[llvm] b336f9d - [InstCombine] Test cases for D154937

Dhruv Chawla via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 11 22:44:36 PDT 2023


Author: Dhruv Chawla
Date: 2023-07-12T11:13:37+05:30
New Revision: b336f9deeba2e1559d398a4fc2a00254c865953f

URL: https://github.com/llvm/llvm-project/commit/b336f9deeba2e1559d398a4fc2a00254c865953f
DIFF: https://github.com/llvm/llvm-project/commit/b336f9deeba2e1559d398a4fc2a00254c865953f.diff

LOG: [InstCombine] Test cases for D154937

Create test cases for the following two folds:

(icmp eq X, C) | (icmp ult Other, (X - C)) -> (icmp ule Other, (X - (C + 1)))
(icmp ne X, C) & (icmp uge Other, (X - C)) -> (icmp ugt Other, (X - (C + 1)))

Differential Revision: https://reviews.llvm.org/D154938

Added: 
    llvm/test/Transforms/InstCombine/and-or-icmp-const-icmp.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmp-const-icmp.ll b/llvm/test/Transforms/InstCombine/and-or-icmp-const-icmp.ll
new file mode 100644
index 00000000000000..a410cacce8dd82
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/and-or-icmp-const-icmp.ll
@@ -0,0 +1,294 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; Tests for foldAndOrOfICmpEqConstantAndICmp
+; https://github.com/llvm/llvm-project/issues/63749
+
+; ==============================================================================
+; (icmp eq X, C) | (icmp ult Other, (X - C)) -> (icmp ule Other, (X - (C + 1)))
+; (icmp ne X, C) & (icmp uge Other, (X - C)) -> (icmp ugt Other, (X - (C + 1)))
+; ==============================================================================
+
+; ==============================================================================
+; Basic tests
+; ==============================================================================
+define i1 @eq_basic(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @eq_basic
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X]], -1
+; CHECK-NEXT:    [[OR:%.*]] = icmp uge i8 [[TMP1]], [[Y]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %c1 = icmp eq i8 %x, 0
+  %c2 = icmp ugt i8 %x, %y
+  %or = or i1 %c1, %c2
+  ret i1 %or
+}
+
+define i1 @ne_basic_equal_5(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ne_basic_equal_5
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[X]], -5
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X]], 5
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[SUB]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %sub = add i8 %x, -5
+  %c1 = icmp ne i8 %x, 5
+  %c2 = icmp ule i8 %sub, %y
+  %and = and i1 %c1, %c2
+  ret i1 %and
+}
+
+define i1 @eq_basic_equal_minus_1(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @eq_basic_equal_minus_1
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], 1
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X]], -1
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %add = add i8 %x, 1
+  %c1 = icmp eq i8 %x, -1
+  %c2 = icmp ugt i8 %add, %y
+  %or = or i1 %c1, %c2
+  ret i1 %or
+}
+
+define i1 @ne_basic_equal_minus_7(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ne_basic_equal_minus_7
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], 7
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X]], -7
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %add = add i8 %x, 7
+  %c1 = icmp ne i8 %x, -7
+  %c2 = icmp ule i8 %add, %y
+  %and = and i1 %c1, %c2
+  ret i1 %and
+}
+
+define i1 @eq_basic_unequal(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @eq_basic_unequal
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[X]], -5
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X]], 6
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i8 [[SUB]], [[Y]]
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %sub = add i8 %x, -5
+  %c1 = icmp eq i8 %x, 6
+  %c2 = icmp ugt i8 %sub, %y
+  %or = or i1 %c1, %c2
+  ret i1 %or
+}
+
+define i1 @ne_basic_unequal(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ne_basic_unequal
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], 7
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X]], -4
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %add = add i8 %x, 7
+  %c1 = icmp ne i8 %x, -4
+  %c2 = icmp ule i8 %add, %y
+  %and = and i1 %c1, %c2
+  ret i1 %and
+}
+
+; ==============================================================================
+; Tests with multiple uses
+; ==============================================================================
+define i1 @eq_multi_c1(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @eq_multi_c1
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X]], -1
+; CHECK-NEXT:    [[OR:%.*]] = icmp uge i8 [[TMP1]], [[Y]]
+; CHECK-NEXT:    call void @use(i1 [[C1]])
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %c1 = icmp eq i8 %x, 0
+  %c2 = icmp ugt i8 %x, %y
+  %or = or i1 %c1, %c2
+  call void @use(i1 %c1)
+  ret i1 %or
+}
+
+define i1 @ne_multi_c2(i8 %x, i8 %y) {
+; CHECK-LABEL: define i1 @ne_multi_c2
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X]], -1
+; CHECK-NEXT:    [[AND:%.*]] = icmp ult i8 [[TMP1]], [[Y]]
+; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %c1 = icmp ne i8 %x, 0
+  %c2 = icmp ule i8 %x, %y
+  %and = and i1 %c1, %c2
+  call void @use(i1 %c2)
+  ret i1 %and
+}
+
+; ==============================================================================
+; Tests with vector types
+; ==============================================================================
+define <2 x i1> @eq_vector(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @eq_vector
+; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X]], <i8 -1, i8 -1>
+; CHECK-NEXT:    [[OR:%.*]] = icmp uge <2 x i8> [[TMP1]], [[Y]]
+; CHECK-NEXT:    ret <2 x i1> [[OR]]
+;
+  %c1 = icmp eq <2 x i8> %x, <i8 0, i8 0>
+  %c2 = icmp ugt <2 x i8> %x, %y
+  %or = or <2 x i1> %c1, %c2
+  ret <2 x i1> %or
+}
+
+define <2 x i1> @ne_vector_equal_5(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @ne_vector_equal_5
+; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[SUB:%.*]] = add <2 x i8> [[X]], <i8 -5, i8 -5>
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne <2 x i8> [[X]], <i8 5, i8 5>
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule <2 x i8> [[SUB]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[C1]], [[C2]]
+; CHECK-NEXT:    ret <2 x i1> [[AND]]
+;
+  %sub = add <2 x i8> %x, <i8 -5, i8 -5>
+  %c1 = icmp ne <2 x i8> %x, <i8 5, i8 5>
+  %c2 = icmp ule <2 x i8> %sub, %y
+  %and = and <2 x i1> %c1, %c2
+  ret <2 x i1> %and
+}
+
+define <2 x i1> @eq_vector_equal_minus_1(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @eq_vector_equal_minus_1
+; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i8> [[X]], <i8 1, i8 1>
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq <2 x i8> [[X]], <i8 -1, i8 -1>
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt <2 x i8> [[ADD]], [[Y]]
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[C1]], [[C2]]
+; CHECK-NEXT:    ret <2 x i1> [[OR]]
+;
+  %add = add <2 x i8> %x, <i8 1, i8 1>
+  %c1 = icmp eq <2 x i8> %x, <i8 -1, i8 -1>
+  %c2 = icmp ugt <2 x i8> %add, %y
+  %or = or <2 x i1> %c1, %c2
+  ret <2 x i1> %or
+}
+
+define <2 x i1> @ne_vector_equal_minus_7(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @ne_vector_equal_minus_7
+; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i8> [[X]], <i8 7, i8 7>
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne <2 x i8> [[X]], <i8 -7, i8 -7>
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule <2 x i8> [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[C1]], [[C2]]
+; CHECK-NEXT:    ret <2 x i1> [[AND]]
+;
+  %add = add <2 x i8> %x, <i8 7, i8 7>
+  %c1 = icmp ne <2 x i8> %x, <i8 -7, i8 -7>
+  %c2 = icmp ule <2 x i8> %add, %y
+  %and = and <2 x i1> %c1, %c2
+  ret <2 x i1> %and
+}
+
+define <2 x i1> @eq_vector_unequal1(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @eq_vector_unequal1
+; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[SUB:%.*]] = add <2 x i8> [[X]], <i8 -5, i8 -5>
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq <2 x i8> [[X]], <i8 2, i8 2>
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt <2 x i8> [[SUB]], [[Y]]
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[C1]], [[C2]]
+; CHECK-NEXT:    ret <2 x i1> [[OR]]
+;
+  %sub = add <2 x i8> %x, <i8 -5, i8 -5>
+  %c1 = icmp eq <2 x i8> %x, <i8 2, i8 2>
+  %c2 = icmp ugt <2 x i8> %sub, %y
+  %or = or <2 x i1> %c1, %c2
+  ret <2 x i1> %or
+}
+
+define <2 x i1> @ne_vector_unequal2(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @ne_vector_unequal2
+; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i8> [[X]], <i8 7, i8 7>
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne <2 x i8> [[X]], <i8 -3, i8 -3>
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule <2 x i8> [[ADD]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[C1]], [[C2]]
+; CHECK-NEXT:    ret <2 x i1> [[AND]]
+;
+  %add = add <2 x i8> %x, <i8 7, i8 7>
+  %c1 = icmp ne <2 x i8> %x, <i8 -3, i8 -3>
+  %c2 = icmp ule <2 x i8> %add, %y
+  %and = and <2 x i1> %c1, %c2
+  ret <2 x i1> %and
+}
+
+; ==============================================================================
+; Tests with undef
+; ==============================================================================
+define <2 x i1> @eq_vector_undef(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @eq_vector_undef
+; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[SUB:%.*]] = add <2 x i8> [[X]], <i8 -5, i8 -5>
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq <2 x i8> [[X]], <i8 5, i8 undef>
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt <2 x i8> [[SUB]], [[Y]]
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[C1]], [[C2]]
+; CHECK-NEXT:    ret <2 x i1> [[OR]]
+;
+  %sub = add <2 x i8> %x, <i8 -5, i8 -5>
+  %c1 = icmp eq <2 x i8> %x, <i8 5, i8 undef>
+  %c2 = icmp ugt <2 x i8> %sub, %y
+  %or = or <2 x i1> %c1, %c2
+  ret <2 x i1> %or
+}
+
+; ==============================================================================
+; Tests with values commuted
+; ==============================================================================
+define i1 @eq_commuted(i8 %x, i8 %py) {
+; CHECK-LABEL: define i1 @eq_commuted
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[PY:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 43, [[PY]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X]], -1
+; CHECK-NEXT:    [[OR:%.*]] = icmp uge i8 [[TMP1]], [[Y]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %y = sdiv i8 43, %py ; thwart complexity-based canonicalization
+  %c1 = icmp eq i8 %x, 0
+  %c2 = icmp ult i8 %y, %x
+  %or = or i1 %c1, %c2
+  ret i1 %or
+}
+
+define i1 @ne_commuted_equal_minus_1(i8 %x, i8 %py) {
+; CHECK-LABEL: define i1 @ne_commuted_equal_minus_1
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[PY:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[PY]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], 1
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X]], -1
+; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[Y]], [[ADD]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %y = sdiv i8 42, %py ; thwart complexity-based canonicalization
+  %add = add i8 %x, 1
+  %c1 = icmp ne i8 %x, -1
+  %c2 = icmp uge i8 %y, %add
+  %and = and i1 %c1, %c2
+  ret i1 %and
+}
+
+declare void @use(i1)


        


More information about the llvm-commits mailing list