[llvm] r322439 - [InstSimplify] fold implied null ptr check (PR35790)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 13 07:44:44 PST 2018


Author: spatel
Date: Sat Jan 13 07:44:44 2018
New Revision: 322439

URL: http://llvm.org/viewvc/llvm-project?rev=322439&view=rev
Log:
[InstSimplify] fold implied null ptr check (PR35790)

This extends rL322327 to handle the pointer cast and should solve:
https://bugs.llvm.org/show_bug.cgi?id=35790

Name: or_eq_zero
  %isnull = icmp eq i64* %p, null
  %x = ptrtoint i64* %p to i64
  %somebits = and i64 %x, %y
  %somebits_are_zero = icmp eq i64 %somebits, 0
  %or = or i1 %somebits_are_zero, %isnull
  =>
  %or = %somebits_are_zero

Name: and_ne_zero
  %isnotnull = icmp ne i64* %p, null
  %x = ptrtoint i64* %p to i64
  %somebits = and i64 %x, %y
  %somebits_are_not_zero = icmp ne i64 %somebits, 0
  %and = and i1 %somebits_are_not_zero, %isnotnull
  =>
  %and = %somebits_are_not_zero

https://rise4fun.com/Alive/CQ3

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=322439&r1=322438&r2=322439&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Sat Jan 13 07:44:44 2018
@@ -1423,27 +1423,28 @@ static Value *simplifyAndOrOfICmpsWithZe
   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)
+  // We have either "(X == 0 || Y == 0)" or "(X != 0 && 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.
+  // that compare implies the other, so we eliminate the other. Optionally, look
+  // through a pointer-to-int cast to match a null check of a pointer type.
 
-  // 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())))
+  // (X == 0) || (([ptrtoint] X && ?) == 0) --> ([ptrtoint] X && ?) == 0
+  // (X == 0) || ((? && [ptrtoint] X) == 0) --> (? && [ptrtoint] X) == 0
+  // (X != 0) && (([ptrtoint] X && ?) != 0) --> ([ptrtoint] X && ?) != 0
+  // (X != 0) && ((? && [ptrtoint] X) != 0) --> (? && [ptrtoint] X) != 0
+  if (match(Y, m_c_And(m_Specific(X), m_Value())) ||
+      match(Y, m_c_And(m_PtrToInt(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())))
+  // (([ptrtoint] Y && ?) == 0) || (Y == 0) --> ([ptrtoint] Y && ?) == 0
+  // ((? && [ptrtoint] Y) == 0) || (Y == 0) --> (? && [ptrtoint] Y) == 0
+  // (([ptrtoint] Y && ?) != 0) && (Y != 0) --> ([ptrtoint] Y && ?) != 0
+  // ((? && [ptrtoint] Y) != 0) && (Y != 0) --> (? && [ptrtoint] Y) != 0
+  if (match(X, m_c_And(m_Specific(Y), m_Value())) ||
+      match(X, m_c_And(m_PtrToInt(m_Specific(Y)), m_Value())))
     return Cmp0;
 
   return nullptr;

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=322439&r1=322438&r2=322439&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/and-or-icmp-zero.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/and-or-icmp-zero.ll Sat Jan 13 07:44:44 2018
@@ -129,12 +129,10 @@ define i1 @and_cmps_eq_zero_with_mask_co
 
 define i1 @or_cmps_ptr_eq_zero_with_mask_commute1(i64* %p, i64 %y) {
 ; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute1(
-; CHECK-NEXT:    [[ISNULL:%.*]] = icmp eq i64* %p, null
 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint i64* %p to i64
 ; 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* %p, null
   %x = ptrtoint i64* %p to i64
@@ -148,12 +146,10 @@ define i1 @or_cmps_ptr_eq_zero_with_mask
 
 define <2 x i1> @or_cmps_ptr_eq_zero_with_mask_commute2(<2 x i64*> %p, <2 x i64> %y) {
 ; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute2(
-; CHECK-NEXT:    [[ISNULL:%.*]] = icmp eq <2 x i64*> %p, zeroinitializer
 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint <2 x i64*> %p to <2 x i64>
 ; 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*> %p, zeroinitializer
   %x = ptrtoint <2 x i64*> %p to <2 x i64>
@@ -167,12 +163,10 @@ define <2 x i1> @or_cmps_ptr_eq_zero_wit
 
 define i1 @or_cmps_ptr_eq_zero_with_mask_commute3(i4* %p, i4 %y) {
 ; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute3(
-; CHECK-NEXT:    [[ISNULL:%.*]] = icmp eq i4* %p, null
 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint i4* %p to i4
 ; 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* %p, null
   %x = ptrtoint i4* %p to i4
@@ -186,12 +180,10 @@ define i1 @or_cmps_ptr_eq_zero_with_mask
 
 define <2 x i1> @or_cmps_ptr_eq_zero_with_mask_commute4(<2 x i4*> %p, <2 x i4> %y) {
 ; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute4(
-; CHECK-NEXT:    [[ISNULL:%.*]] = icmp eq <2 x i4*> %p, zeroinitializer
 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint <2 x i4*> %p to <2 x i4>
 ; 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*> %p, zeroinitializer
   %x = ptrtoint <2 x i4*> %p to <2 x i4>
@@ -205,12 +197,10 @@ define <2 x i1> @or_cmps_ptr_eq_zero_wit
 
 define <3 x i1> @and_cmps_ptr_eq_zero_with_mask_commute1(<3 x i4*> %p, <3 x i4> %y) {
 ; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute1(
-; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne <3 x i4*> %p, zeroinitializer
 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint <3 x i4*> %p to <3 x i4>
 ; 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*> %p, zeroinitializer
   %x = ptrtoint <3 x i4*> %p to <3 x i4>
@@ -224,12 +214,10 @@ define <3 x i1> @and_cmps_ptr_eq_zero_wi
 
 define i1 @and_cmps_ptr_eq_zero_with_mask_commute2(i4* %p, i4 %y) {
 ; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute2(
-; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne i4* %p, null
 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint i4* %p to i4
 ; 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* %p, null
   %x = ptrtoint i4* %p to i4
@@ -243,12 +231,10 @@ define i1 @and_cmps_ptr_eq_zero_with_mas
 
 define <3 x i1> @and_cmps_ptr_eq_zero_with_mask_commute3(<3 x i64*> %p, <3 x i64> %y) {
 ; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute3(
-; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne <3 x i64*> %p, zeroinitializer
 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint <3 x i64*> %p to <3 x i64>
 ; 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*> %p, zeroinitializer
   %x = ptrtoint <3 x i64*> %p to <3 x i64>
@@ -262,12 +248,10 @@ define <3 x i1> @and_cmps_ptr_eq_zero_wi
 
 define i1 @and_cmps_ptr_eq_zero_with_mask_commute4(i64* %p, i64 %y) {
 ; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute4(
-; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne i64* %p, null
 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint i64* %p to i64
 ; 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* %p, null
   %x = ptrtoint i64* %p to i64




More information about the llvm-commits mailing list