[llvm] r322327 - [InstSimplify] fold implied cmp with zero (PR35790)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 11 15:27:37 PST 2018
Author: spatel
Date: Thu Jan 11 15:27:37 2018
New Revision: 322327
URL: http://llvm.org/viewvc/llvm-project?rev=322327&view=rev
Log:
[InstSimplify] fold implied cmp with zero (PR35790)
This doesn't handle the more complicated case in the bug report yet:
https://bugs.llvm.org/show_bug.cgi?id=35790
For that, we have to match / look through a cast.
Modified:
llvm/trunk/lib/Analysis/InstructionSimplify.cpp
llvm/trunk/test/Transforms/InstSimplify/and-or-icmp-zero.ll
Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=322327&r1=322326&r2=322327&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Thu Jan 11 15:27:37 2018
@@ -1413,6 +1413,42 @@ static Value *simplifyAndOrOfICmpsWithCo
return nullptr;
}
+static Value *simplifyAndOrOfICmpsWithZero(ICmpInst *Cmp0, ICmpInst *Cmp1,
+ bool IsAnd) {
+ ICmpInst::Predicate P0 = Cmp0->getPredicate(), P1 = Cmp1->getPredicate();
+ if (!match(Cmp0->getOperand(1), m_Zero()) ||
+ !match(Cmp1->getOperand(1), m_Zero()) || P0 != P1)
+ return nullptr;
+
+ if ((IsAnd && P0 != ICmpInst::ICMP_NE) || (!IsAnd && P1 != ICmpInst::ICMP_EQ))
+ return nullptr;
+
+ // We have one of:
+ // or (icmp eq X, 0), (icmp eq Y, 0)
+ // and (icmp ne X, 0), (icmp ne Y, 0)
+ Value *X = Cmp0->getOperand(0);
+ Value *Y = Cmp1->getOperand(0);
+
+ // If one of the compares is a masked version of a (not) null check, then
+ // that compare implies the other, so we eliminate the other.
+
+ // or (icmp eq X, 0), (icmp eq (and X, ?), 0) --> icmp eq (and X, ?), 0
+ // or (icmp eq X, 0), (icmp eq (and ?, X), 0) --> icmp eq (and ?, X), 0
+ // and (icmp ne X, 0), (icmp ne (and X, ?), 0) --> icmp ne (and X, ?), 0
+ // and (icmp ne X, 0), (icmp ne (and ?, X), 0) --> icmp ne (and ?, X), 0
+ if (match(Y, m_c_And(m_Specific(X), m_Value())))
+ return Cmp1;
+
+ // or (icmp eq (and Y, ?), 0), (icmp eq Y, 0) --> icmp eq (and Y, ?), 0
+ // or (icmp eq (and ?, Y), 0), (icmp eq Y, 0) --> icmp eq (and ?, Y), 0
+ // and (icmp ne (and Y, ?), 0), (icmp ne Y, 0) --> icmp ne (and Y, ?), 0
+ // and (icmp ne (and ?, Y), 0), (icmp ne Y, 0) --> icmp ne (and ?, Y), 0
+ if (match(X, m_c_And(m_Specific(Y), m_Value())))
+ return Cmp0;
+
+ return nullptr;
+}
+
static Value *simplifyAndOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1) {
// (icmp (add V, C0), C1) & (icmp V, C0)
ICmpInst::Predicate Pred0, Pred1;
@@ -1473,6 +1509,9 @@ static Value *simplifyAndOfICmps(ICmpIns
if (Value *X = simplifyAndOrOfICmpsWithConstants(Op0, Op1, true))
return X;
+ if (Value *X = simplifyAndOrOfICmpsWithZero(Op0, Op1, true))
+ return X;
+
if (Value *X = simplifyAndOfICmpsWithAdd(Op0, Op1))
return X;
if (Value *X = simplifyAndOfICmpsWithAdd(Op1, Op0))
@@ -1541,6 +1580,9 @@ static Value *simplifyOrOfICmps(ICmpInst
if (Value *X = simplifyAndOrOfICmpsWithConstants(Op0, Op1, false))
return X;
+ if (Value *X = simplifyAndOrOfICmpsWithZero(Op0, Op1, false))
+ return X;
+
if (Value *X = simplifyOrOfICmpsWithAdd(Op0, Op1))
return X;
if (Value *X = simplifyOrOfICmpsWithAdd(Op1, Op0))
Modified: llvm/trunk/test/Transforms/InstSimplify/and-or-icmp-zero.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/and-or-icmp-zero.ll?rev=322327&r1=322326&r2=322327&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/and-or-icmp-zero.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/and-or-icmp-zero.ll Thu Jan 11 15:27:37 2018
@@ -8,11 +8,9 @@
define i1 @or_cmps_eq_zero_with_mask_commute1(i64 %x, i64 %y) {
; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute1(
-; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 %x, 0
; CHECK-NEXT: [[SOMEBITS:%.*]] = and i64 %x, %y
; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i64 [[SOMEBITS]], 0
-; CHECK-NEXT: [[R:%.*]] = or i1 [[SOMEBITS_ARE_ZERO]], [[ISNULL]]
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_ZERO]]
;
%isnull = icmp eq i64 %x, 0
%somebits = and i64 %x, %y
@@ -25,11 +23,9 @@ define i1 @or_cmps_eq_zero_with_mask_com
define <2 x i1> @or_cmps_eq_zero_with_mask_commute2(<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute2(
-; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq <2 x i64> %x, zeroinitializer
; CHECK-NEXT: [[SOMEBITS:%.*]] = and <2 x i64> %x, %y
; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i64> [[SOMEBITS]], zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[ISNULL]], [[SOMEBITS_ARE_ZERO]]
-; CHECK-NEXT: ret <2 x i1> [[R]]
+; CHECK-NEXT: ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
;
%isnull = icmp eq <2 x i64> %x, zeroinitializer
%somebits = and <2 x i64> %x, %y
@@ -42,11 +38,9 @@ define <2 x i1> @or_cmps_eq_zero_with_ma
define i1 @or_cmps_eq_zero_with_mask_commute3(i4 %x, i4 %y) {
; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute3(
-; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i4 %x, 0
; CHECK-NEXT: [[SOMEBITS:%.*]] = and i4 %y, %x
; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i4 [[SOMEBITS]], 0
-; CHECK-NEXT: [[R:%.*]] = or i1 [[SOMEBITS_ARE_ZERO]], [[ISNULL]]
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_ZERO]]
;
%isnull = icmp eq i4 %x, 0
%somebits = and i4 %y, %x
@@ -59,11 +53,9 @@ define i1 @or_cmps_eq_zero_with_mask_com
define <2 x i1> @or_cmps_eq_zero_with_mask_commute4(<2 x i4> %x, <2 x i4> %y) {
; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute4(
-; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq <2 x i4> %x, zeroinitializer
; CHECK-NEXT: [[SOMEBITS:%.*]] = and <2 x i4> %y, %x
; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[SOMEBITS]], zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[ISNULL]], [[SOMEBITS_ARE_ZERO]]
-; CHECK-NEXT: ret <2 x i1> [[R]]
+; CHECK-NEXT: ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
;
%isnull = icmp eq <2 x i4> %x, zeroinitializer
%somebits = and <2 x i4> %y, %x
@@ -76,11 +68,9 @@ define <2 x i1> @or_cmps_eq_zero_with_ma
define <3 x i1> @and_cmps_eq_zero_with_mask_commute1(<3 x i4> %x, <3 x i4> %y) {
; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute1(
-; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne <3 x i4> %x, zeroinitializer
; CHECK-NEXT: [[SOMEBITS:%.*]] = and <3 x i4> %x, %y
; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i4> [[SOMEBITS]], zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = and <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]], [[ISNOTNULL]]
-; CHECK-NEXT: ret <3 x i1> [[R]]
+; CHECK-NEXT: ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
;
%isnotnull = icmp ne <3 x i4> %x, zeroinitializer
%somebits = and <3 x i4> %x, %y
@@ -93,11 +83,9 @@ define <3 x i1> @and_cmps_eq_zero_with_m
define i1 @and_cmps_eq_zero_with_mask_commute2(i4 %x, i4 %y) {
; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute2(
-; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne i4 %x, 0
; CHECK-NEXT: [[SOMEBITS:%.*]] = and i4 %x, %y
; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i4 [[SOMEBITS]], 0
-; CHECK-NEXT: [[R:%.*]] = and i1 [[ISNOTNULL]], [[SOMEBITS_ARE_NOT_ZERO]]
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
;
%isnotnull = icmp ne i4 %x, 0
%somebits = and i4 %x, %y
@@ -110,11 +98,9 @@ define i1 @and_cmps_eq_zero_with_mask_co
define <3 x i1> @and_cmps_eq_zero_with_mask_commute3(<3 x i64> %x, <3 x i64> %y) {
; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute3(
-; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne <3 x i64> %x, zeroinitializer
; CHECK-NEXT: [[SOMEBITS:%.*]] = and <3 x i64> %y, %x
; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i64> [[SOMEBITS]], zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = and <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]], [[ISNOTNULL]]
-; CHECK-NEXT: ret <3 x i1> [[R]]
+; CHECK-NEXT: ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
;
%isnotnull = icmp ne <3 x i64> %x, zeroinitializer
%somebits = and <3 x i64> %y, %x
@@ -127,11 +113,9 @@ define <3 x i1> @and_cmps_eq_zero_with_m
define i1 @and_cmps_eq_zero_with_mask_commute4(i64 %x, i64 %y) {
; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute4(
-; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne i64 %x, 0
; CHECK-NEXT: [[SOMEBITS:%.*]] = and i64 %y, %x
; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i64 [[SOMEBITS]], 0
-; CHECK-NEXT: [[R:%.*]] = and i1 [[ISNOTNULL]], [[SOMEBITS_ARE_NOT_ZERO]]
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
;
%isnotnull = icmp ne i64 %x, 0
%somebits = and i64 %y, %x
More information about the llvm-commits
mailing list