[llvm] f623df6 - [InstSimplify] Add tests for monotonic icmps (NFC)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 28 08:05:17 PST 2024


Author: Nikita Popov
Date: 2024-11-28T17:05:06+01:00
New Revision: f623df6376b94906671ad6e875e6f504b74fed31

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

LOG: [InstSimplify] Add tests for monotonic icmps (NFC)

Added: 
    llvm/test/Transforms/InstSimplify/icmp-monotonic.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstSimplify/icmp-monotonic.ll b/llvm/test/Transforms/InstSimplify/icmp-monotonic.ll
new file mode 100644
index 00000000000000..a1daa6bd7b4021
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/icmp-monotonic.ll
@@ -0,0 +1,242 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
+
+define i1 @lshr_or_ule(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @lshr_or_ule(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %x, %y
+  %op2 = or i32 %x, %z
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @lshr_or_uge_swapped(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @lshr_or_uge_swapped(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[OP2]], [[OP1]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %x, %y
+  %op2 = or i32 %x, %z
+  %cmp = icmp uge i32 %op2, %op1
+  ret i1 %cmp
+}
+
+define i1 @lshr_or_ugt(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @lshr_or_ugt(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %x, %y
+  %op2 = or i32 %x, %z
+  %cmp = icmp ugt i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @lshr_or_ult_wrong_pred(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @lshr_or_ult_wrong_pred(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %x, %y
+  %op2 = or i32 %x, %z
+  %cmp = icmp ult i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @lshr_or_sle_wrong_pred(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @lshr_or_sle_wrong_pred(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %x, %y
+  %op2 = or i32 %x, %z
+  %cmp = icmp sle i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @lshr_or_swapped_ule(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @lshr_or_swapped_ule(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[Z]], [[X]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %x, %y
+  %op2 = or i32 %z, %x
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @lshr_or_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @lshr_or_ule_invalid_swapped(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[Y]], [[X]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %y, %x
+  %op2 = or i32 %x, %z
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @and_uadd_sat_ule(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @and_uadd_sat_ule(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = and i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Z]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = and i32 %x, %y
+  %op2 = call i32 @llvm.uadd.sat(i32 %x, i32 %z)
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @urem_or_ule(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @urem_or_ule(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = urem i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = urem i32 %x, %y
+  %op2 = or i32 %x, %z
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @urem_or_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @urem_or_ule_invalid_swapped(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = urem i32 [[Y]], [[X]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = urem i32 %y, %x
+  %op2 = or i32 %x, %z
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @udiv_or_ule(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @udiv_or_ule(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = udiv i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = udiv i32 %x, %y
+  %op2 = or i32 %x, %z
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @udiv_or_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @udiv_or_ule_invalid_swapped(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = udiv i32 [[Y]], [[X]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = udiv i32 %y, %x
+  %op2 = or i32 %x, %z
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @usub_sat_uadd_sat_ule(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @usub_sat_uadd_sat_ule(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[OP2:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Z]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = call i32 @llvm.usub.sat(i32 %x, i32 %y)
+  %op2 = call i32 @llvm.uadd.sat(i32 %x, i32 %z)
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @usub_sat_uadd_sat_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @usub_sat_uadd_sat_ule_invalid_swapped(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[Y]], i32 [[X]])
+; CHECK-NEXT:    [[OP2:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Z]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = call i32 @llvm.usub.sat(i32 %y, i32 %x)
+  %op2 = call i32 @llvm.uadd.sat(i32 %x, i32 %z)
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @lshr_or_ule_no_common_op(i32 %x, i32 %y, i32 %z, i32 %w) {
+; CHECK-LABEL: define i1 @lshr_or_ule_no_common_op(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], i32 [[W:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[W]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %x, %y
+  %op2 = or i32 %w, %z
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}
+
+define i1 @lshr_or_ule_nested(i32 %x, i32 %y, i32 %z, i32 %w) {
+; CHECK-LABEL: define i1 @lshr_or_ule_nested(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], i32 [[W:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[OP3:%.*]] = or i32 [[OP2]], [[W]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP3]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %x, %y
+  %op2 = or i32 %x, %z
+  %op3 = or i32 %op2, %w
+  %cmp = icmp ule i32 %op1, %op3
+  ret i1 %cmp
+}
+
+define i1 @lshr_add_ule_non_monotonic(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @lshr_add_ule_non_monotonic(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[OP2:%.*]] = add i32 [[X]], [[Z]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %op1 = lshr i32 %x, %y
+  %op2 = add i32 %x, %z
+  %cmp = icmp ule i32 %op1, %op2
+  ret i1 %cmp
+}


        


More information about the llvm-commits mailing list