[llvm] 2bec8d6 - [InstCombine] Fold X + Y + C u< X
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 25 03:53:50 PDT 2022
Author: Nikita Popov
Date: 2022-04-25T12:53:39+02:00
New Revision: 2bec8d6d59a1c90f2593040fb2b4eb339d83f8c9
URL: https://github.com/llvm/llvm-project/commit/2bec8d6d59a1c90f2593040fb2b4eb339d83f8c9
DIFF: https://github.com/llvm/llvm-project/commit/2bec8d6d59a1c90f2593040fb2b4eb339d83f8c9.diff
LOG: [InstCombine] Fold X + Y + C u< X
This is a variation on the X + Y u< X fold with an extra constant.
Proof: https://alive2.llvm.org/ce/z/VNb8pY
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-add.ll
llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 3e6a2f0d108a1..6c70299199c21 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3970,6 +3970,24 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
(Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULE))
return new ICmpInst(Pred, X, Builder.CreateNot(Op0));
+ {
+ // (Op1 + X) + C u</u>= Op1 --> ~C - X u</u>= Op1
+ Constant *C;
+ if (match(Op0, m_OneUse(m_Add(m_c_Add(m_Specific(Op1), m_Value(X)),
+ m_ImmConstant(C)))) &&
+ (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_UGE)) {
+ Constant *C2 = ConstantExpr::getNot(C);
+ return new ICmpInst(Pred, Builder.CreateSub(C2, X), Op1);
+ }
+ // Op0 u>/u<= (Op0 + X) + C --> Op0 u>/u<= ~C - X
+ if (match(Op1, m_OneUse(m_Add(m_c_Add(m_Specific(Op0), m_Value(X)),
+ m_ImmConstant(C)))) &&
+ (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULE)) {
+ Constant *C2 = ConstantExpr::getNot(C);
+ return new ICmpInst(Pred, Op0, Builder.CreateSub(C2, X));
+ }
+ }
+
{
// Similar to above: an unsigned overflow comparison may use offset + mask:
// ((Op1 + C) & C) u< Op1 --> Op1 != 0
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index 308adcab05391..849946ce84af5 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -1027,9 +1027,8 @@ define i32 @decrement_min(i32 %x) {
define i1 @icmp_add_add_C(i32 %a, i32 %b) {
; CHECK-LABEL: @icmp_add_add_C(
-; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], [[A:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%add1 = add i32 %a, %b
@@ -1040,9 +1039,8 @@ define i1 @icmp_add_add_C(i32 %a, i32 %b) {
define i1 @icmp_add_add_C_pred(i32 %a, i32 %b) {
; CHECK-LABEL: @icmp_add_add_C_pred(
-; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ADD2]], [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[TMP1]], [[A:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%add1 = add i32 %a, %b
@@ -1079,9 +1077,8 @@ define i1 @icmp_add_add_C_wrong_operand(i32 %a, i32 %b, i32 %c) {
define i1 @icmp_add_add_C_
diff erent_const(i32 %a, i32 %b) {
; CHECK-LABEL: @icmp_add_add_C_
diff erent_const(
-; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 42
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 -43, [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], [[A:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%add1 = add i32 %a, %b
@@ -1092,9 +1089,8 @@ define i1 @icmp_add_add_C_
diff erent_const(i32 %a, i32 %b) {
define <2 x i1> @icmp_add_add_C_vector(<2 x i8> %a, <2 x i8> %b) {
; CHECK-LABEL: @icmp_add_add_C_vector(
-; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[ADD2:%.*]] = add <2 x i8> [[ADD1]], <i8 10, i8 20>
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[ADD2]], [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i8> <i8 -11, i8 -21>, [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[TMP1]], [[A:%.*]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%add1 = add <2 x i8> %a, %b
@@ -1105,9 +1101,8 @@ define <2 x i1> @icmp_add_add_C_vector(<2 x i8> %a, <2 x i8> %b) {
define <2 x i1> @icmp_add_add_C_vector_undef(<2 x i8> %a, <2 x i8> %b) {
; CHECK-LABEL: @icmp_add_add_C_vector_undef(
-; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[ADD2:%.*]] = add <2 x i8> [[ADD1]], <i8 10, i8 undef>
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[ADD2]], [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i8> <i8 -11, i8 undef>, [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[TMP1]], [[A:%.*]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%add1 = add <2 x i8> %a, %b
@@ -1118,9 +1113,8 @@ define <2 x i1> @icmp_add_add_C_vector_undef(<2 x i8> %a, <2 x i8> %b) {
define i1 @icmp_add_add_C_comm1(i32 %a, i32 %b) {
; CHECK-LABEL: @icmp_add_add_C_comm1(
-; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
-; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], [[A:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%add1 = add i32 %b, %a
@@ -1132,9 +1126,8 @@ define i1 @icmp_add_add_C_comm1(i32 %a, i32 %b) {
define i1 @icmp_add_add_C_comm2(i32 %X, i32 %b) {
; CHECK-LABEL: @icmp_add_add_C_comm2(
; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[X:%.*]]
-; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A]], [[B:%.*]]
-; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], [[ADD2]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = udiv i32 42, %X ; thwart complexity-based canonicalization
@@ -1147,9 +1140,8 @@ define i1 @icmp_add_add_C_comm2(i32 %X, i32 %b) {
define i1 @icmp_add_add_C_comm2_pred(i32 %X, i32 %b) {
; CHECK-LABEL: @icmp_add_add_C_comm2_pred(
; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[X:%.*]]
-; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A]], [[B:%.*]]
-; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[A]], [[ADD2]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[A]], [[TMP1]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = udiv i32 42, %X ; thwart complexity-based canonicalization
@@ -1177,9 +1169,8 @@ define i1 @icmp_add_add_C_comm2_wrong_pred(i32 %X, i32 %b) {
define i1 @icmp_add_add_C_comm3(i32 %X, i32 %b) {
; CHECK-LABEL: @icmp_add_add_C_comm3(
; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[X:%.*]]
-; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A]], [[B:%.*]]
-; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], [[ADD2]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = udiv i32 42, %X ; thwart complexity-based canonicalization
@@ -1208,8 +1199,8 @@ define i1 @icmp_add_add_C_extra_use2(i32 %a, i32 %b) {
; CHECK-LABEL: @icmp_add_add_C_extra_use2(
; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: call void @use(i32 [[ADD1]])
-; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], [[A]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%add1 = add i32 %a, %b
diff --git a/llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll b/llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll
index 08def405c58b9..049b61eb2d81b 100644
--- a/llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll
+++ b/llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll
@@ -254,7 +254,7 @@ define i1 @t7(i8 %base, i8 %offset) {
; CHECK-LABEL: @t7(
; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])
-; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[ADJUSTED]], -1
+; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i8 [[TMP1]], [[BASE]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
@@ -270,7 +270,7 @@ define i1 @t7_logical(i8 %base, i8 %offset) {
; CHECK-LABEL: @t7_logical(
; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])
-; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[ADJUSTED]], -1
+; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i8 [[TMP1]], [[BASE]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
More information about the llvm-commits
mailing list