[llvm] Simplify `(a % b) lt/ge (b-1)` into `(a % b) eq/ne (b-1)` (PR #72504)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 6 02:31:53 PST 2024
https://github.com/elhewaty updated https://github.com/llvm/llvm-project/pull/72504
>From 0638fa7a2e59bd7d623b833e830968fba2f05d0e Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Fri, 17 Nov 2023 16:20:59 +0200
Subject: [PATCH] [InstCombine] Add test coverage for (a % b) lt/le/ge/gt
(b(-/+)1) (NFC).
---
llvm/test/Transforms/InstCombine/icmp.ll | 290 +++++++++++++++++++++++
1 file changed, 290 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 78ac730cf026ed..8a351d10e1f240 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -10,6 +10,296 @@ declare void @use_i8(i8)
declare void @use_i32(i32)
declare void @use_i64(i64)
+; tests for (x % c) >=/ < (c - 1), where c >= 0
+define i1 @srem_sge_test1(i64 %x) {
+; CHECK-LABEL: @srem_sge_test1(
+; CHECK-NEXT: [[Y:%.*]] = srem i64 [[X:%.*]], 34360750831
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Y]], 34360750829
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i64 %x, 34360750831
+ %cmp = icmp sge i64 %y, 34360750830
+ ret i1 %cmp
+}
+
+define i1 @srem_slt_test1(i64 %x) {
+; CHECK-LABEL: @srem_slt_test1(
+; CHECK-NEXT: [[Y:%.*]] = srem i64 [[X:%.*]], 34360750831
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[Y]], 34360750830
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i64 %x, 34360750831
+ %cmp = icmp slt i64 %y, 34360750830
+ ret i1 %cmp
+}
+
+define i1 @srem_sge_test2(i32 %x) {
+; CHECK-LABEL: @srem_sge_test2(
+; CHECK-NEXT: [[Y:%.*]] = srem i32 [[X:%.*]], 1074977277
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[Y]], 1074977275
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i32 %x, 1074977277
+ %cmp = icmp sge i32 %y, 1074977276
+ ret i1 %cmp
+}
+
+define i1 @srem_slt_test2(i32 %x) {
+; CHECK-LABEL: @srem_slt_test2(
+; CHECK-NEXT: [[Y:%.*]] = srem i32 [[X:%.*]], 1074977277
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 1074977276
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i32 %x, 1074977277
+ %cmp = icmp slt i32 %y, 1074977276
+ ret i1 %cmp
+}
+
+define i1 @srem_sge_test3(i16 %x) {
+; CHECK-LABEL: @srem_sge_test3(
+; CHECK-NEXT: [[Y:%.*]] = srem i16 [[X:%.*]], 2259
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[Y]], 2257
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i16 %x, 2259
+ %cmp = icmp sge i16 %y, 2258
+ ret i1 %cmp
+}
+
+define i1 @srem_slt_test3(i16 %x) {
+; CHECK-LABEL: @srem_slt_test3(
+; CHECK-NEXT: [[Y:%.*]] = srem i16 [[X:%.*]], 2259
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[Y]], 2258
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i16 %x, 2259
+ %cmp = icmp slt i16 %y, 2258
+ ret i1 %cmp
+}
+
+define i1 @srem_sge_test4(i8 %x) {
+; CHECK-LABEL: @srem_sge_test4(
+; CHECK-NEXT: ret i1 true
+;
+ %y = srem i8 %x, 133
+ %cmp = icmp sge i8 %y, 132
+ ret i1 %cmp
+}
+
+define i1 @srem_slt_test4(i8 %x) {
+; CHECK-LABEL: @srem_slt_test4(
+; CHECK-NEXT: ret i1 false
+;
+ %y = srem i8 %x, 133
+ %cmp = icmp slt i8 %y, 132
+ ret i1 %cmp
+}
+
+define i1 @test_srem_slt_constant(i32 %a) {
+; CHECK-LABEL: @test_srem_slt_constant(
+; CHECK-NEXT: [[Y:%.*]] = srem i32 [[A:%.*]], 512
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 511
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i32 %a, 512
+ %cmp = icmp slt i32 %y, 511
+ ret i1 %cmp
+}
+
+define i1 @test_srem_sge_constant(i32 %a) {
+; CHECK-LABEL: @test_srem_sge_constant(
+; CHECK-NEXT: [[Y:%.*]] = srem i32 [[A:%.*]], 512
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[Y]], 510
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i32 %a, 512
+ %cmp = icmp sge i32 %y, 511
+ ret i1 %cmp
+}
+
+define <2 x i1> @test_srem_slt_constant_splat(<2 x i32> %a) {
+; CHECK-LABEL: @test_srem_slt_constant_splat(
+; CHECK-NEXT: [[Y:%.*]] = srem <2 x i32> [[A:%.*]], <i32 512, i32 512>
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[Y]], <i32 511, i32 511>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %y = srem <2 x i32> %a, <i32 512, i32 512>
+ %cmp = icmp slt <2 x i32> %y, <i32 511, i32 511>
+ ret <2 x i1> %cmp
+}
+
+define <2 x i1> @test_srem_sge_constant_splat(<2 x i32> %a) {
+; CHECK-LABEL: @test_srem_sge_constant_splat(
+; CHECK-NEXT: [[Y:%.*]] = srem <2 x i32> [[A:%.*]], <i32 512, i32 512>
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[Y]], <i32 510, i32 510>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %y = srem <2 x i32> %a, <i32 512, i32 512>
+ %cmp = icmp sge <2 x i32> %y, <i32 511, i32 511>
+ ret <2 x i1> %cmp
+}
+
+; tests for (x % c) <=/> (c + 1), where y < 0
+define i1 @srem_sgt_test(i16 %x) {
+; CHECK-LABEL: @srem_sgt_test(
+; CHECK-NEXT: [[Y:%.*]] = srem i16 [[X:%.*]], 2259
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[Y]], -2258
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i16 %x, -2259
+ %cmp = icmp sgt i16 %y, -2258
+ ret i1 %cmp
+}
+
+define i1 @srem_sle_test(i16 %x) {
+; CHECK-LABEL: @srem_sle_test(
+; CHECK-NEXT: [[Y:%.*]] = srem i16 [[X:%.*]], 2259
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[Y]], -2257
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = srem i16 %x, -2259
+ %cmp = icmp sle i16 %y, -2258
+ ret i1 %cmp
+}
+
+define <2 x i1> @test_srem_sgt_constant_splat(<2 x i32> %a) {
+; CHECK-LABEL: @test_srem_sgt_constant_splat(
+; CHECK-NEXT: [[Y:%.*]] = srem <2 x i32> [[A:%.*]], <i32 512, i32 512>
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[Y]], <i32 -511, i32 -511>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %y = srem <2 x i32> %a, <i32 -512, i32 -512>
+ %cmp = icmp sgt <2 x i32> %y, <i32 -511, i32 -511>
+ ret <2 x i1> %cmp
+}
+
+define <2 x i1> @test_srem_sle_constant_splat(<2 x i32> %a) {
+; CHECK-LABEL: @test_srem_sle_constant_splat(
+; CHECK-NEXT: [[Y:%.*]] = srem <2 x i32> [[A:%.*]], <i32 512, i32 512>
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[Y]], <i32 -510, i32 -510>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %y = srem <2 x i32> %a, <i32 -512, i32 -512>
+ %cmp = icmp sle <2 x i32> %y, <i32 -511, i32 -511>
+ ret <2 x i1> %cmp
+}
+
+; tests for handling urem w/ slt/sge/uge/ult
+define i1 @test_urem_slt(i32 %x) {
+; CHECK-LABEL: @test_urem_slt(
+; CHECK-NEXT: [[Y:%.*]] = urem i32 [[X:%.*]], 12235
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[Y]], 12234
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = urem i32 %x, 12235
+ %cmp = icmp slt i32 %y, 12234
+ ret i1 %cmp
+}
+
+define i1 @test_urem_sge(i32 %x) {
+; CHECK-LABEL: @test_urem_sge(
+; CHECK-NEXT: [[Y:%.*]] = urem i32 [[X:%.*]], 13546
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y]], 13544
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = urem i32 %x, 13546
+ %cmp = icmp sge i32 %y, 13545
+ ret i1 %cmp
+}
+
+define i1 @test_urem_uge(i32 %x) {
+; CHECK-LABEL: @test_urem_uge(
+; CHECK-NEXT: [[Y:%.*]] = urem i32 [[X:%.*]], 18642
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y]], 18640
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = urem i32 %x, 18642
+ %cmp = icmp uge i32 %y, 18641
+ ret i1 %cmp
+}
+
+define i1 @test_urem_ult(i32 %x) {
+; CHECK-LABEL: @test_urem_ult(
+; CHECK-NEXT: [[Y:%.*]] = urem i32 [[X:%.*]], 15344
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[Y]], 15343
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y = urem i32 %x, 15344
+ %cmp = icmp ult i32 %y, 15343
+ ret i1 %cmp
+}
+
+define <2 x i1> @test_urem_slt_constant_splat(<2 x i32> %a) {
+; CHECK-LABEL: @test_urem_slt_constant_splat(
+; CHECK-NEXT: [[Y:%.*]] = srem <2 x i32> [[A:%.*]], <i32 512, i32 512>
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[Y]], <i32 511, i32 511>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %y = srem <2 x i32> %a, <i32 512, i32 512>
+ %cmp = icmp slt <2 x i32> %y, <i32 511, i32 511>
+ ret <2 x i1> %cmp
+}
+
+define <2 x i1> @test_urem_sge_constant_splat(<2 x i32> %a) {
+; CHECK-LABEL: @test_urem_sge_constant_splat(
+; CHECK-NEXT: [[Y:%.*]] = srem <2 x i32> [[A:%.*]], <i32 512, i32 512>
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[Y]], <i32 510, i32 510>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %y = srem <2 x i32> %a, <i32 512, i32 512>
+ %cmp = icmp sge <2 x i32> %y, <i32 511, i32 511>
+ ret <2 x i1> %cmp
+}
+
+define <2 x i1> @test_urem_uge_constant_splat(<2 x i32> %a) {
+; CHECK-LABEL: @test_urem_uge_constant_splat(
+; CHECK-NEXT: [[Y:%.*]] = srem <2 x i32> [[A:%.*]], <i32 512, i32 512>
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[Y]], <i32 510, i32 510>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %y = srem <2 x i32> %a, <i32 512, i32 512>
+ %cmp = icmp uge <2 x i32> %y, <i32 511, i32 511>
+ ret <2 x i1> %cmp
+}
+
+define <2 x i1> @test_urem_ult_constant_splat(<2 x i32> %a) {
+; CHECK-LABEL: @test_urem_ult_constant_splat(
+; CHECK-NEXT: [[Y:%.*]] = srem <2 x i32> [[A:%.*]], <i32 512, i32 512>
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[Y]], <i32 511, i32 511>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %y = srem <2 x i32> %a, <i32 512, i32 512>
+ %cmp = icmp ult <2 x i32> %y, <i32 511, i32 511>
+ ret <2 x i1> %cmp
+}
+
+; negative tests
+define i1 @srem_slt_neg_test(i8 %x, i8 %C) {
+; CHECK-LABEL: @srem_slt_neg_test(
+; CHECK-NEXT: [[CMINUS1:%.*]] = add i8 [[C:%.*]], -1
+; CHECK-NEXT: [[Y:%.*]] = srem i8 [[X:%.*]], [[C]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[Y]], [[CMINUS1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %Cminus1 = add i8 %C, -1
+ %y = srem i8 %x, %C
+ %cmp = icmp slt i8 %y, %Cminus1
+ ret i1 %cmp
+}
+
+define i1 @srem_sge_neg_test(i8 %x, i8 %C) {
+; CHECK-LABEL: @srem_sge_neg_test(
+; CHECK-NEXT: [[CMINUS1:%.*]] = add i8 [[C:%.*]], -1
+; CHECK-NEXT: [[Y:%.*]] = srem i8 [[X:%.*]], [[C]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[Y]], [[CMINUS1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %Cminus1 = add i8 %C, -1
+ %y = srem i8 %x, %C
+ %cmp = icmp sge i8 %y, %Cminus1
+ ret i1 %cmp
+}
+
define i32 @test1(i32 %X) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31
More information about the llvm-commits
mailing list