[InstCombine] icmp eq/ne (gep inbounds P, Idx..), null -> icmp eq/ne P, null for...
authorPhilip Reames <listmail@philipreames.com>
Mon, 26 Aug 2019 19:11:49 +0000 (19:11 +0000)
committerPhilip Reames <listmail@philipreames.com>
Mon, 26 Aug 2019 19:11:49 +0000 (19:11 +0000)
Extend the transform introduced in https://reviews.llvm.org/D66608 to work for vector geps as well.

Differential Revision: https://reviews.llvm.org/D66671

llvm-svn: 369949

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/gep-inbounds-null.ll

index b80e9ade75d4620e6e4052ee834ba22a7be4deaf..c4491178018a605b74366e8775b982420145a4f1 100644 (file)
@@ -895,7 +895,6 @@ Instruction *InstCombiner::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
     return new ICmpInst(ICmpInst::getSignedPredicate(Cond), Offset,
                         Constant::getNullValue(Offset->getType()));
   } else if (GEPLHS->isInBounds() && ICmpInst::isEquality(Cond) &&
-             GEPLHS->getType()->isPointerTy() && // TODO: extend to vector geps
              isa<Constant>(RHS) && cast<Constant>(RHS)->isNullValue() &&
              !NullPointerIsDefined(I.getFunction(),
                                    RHS->getType()->getPointerAddressSpace())) {
@@ -914,7 +913,13 @@ Instruction *InstCombiner::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
     // In general, we're allowed to make values less poison (i.e. remove
     //   sources of full UB), so in this case, we just select between the two
     //   non-poison cases (1 and 4 above).
+    //
+    // For vectors, we apply the same reasoning on a per-lane basis.
     auto *Base = GEPLHS->getPointerOperand();
+    if (GEPLHS->getType()->isVectorTy() && Base->getType()->isPointerTy()) {
+      int NumElts = GEPLHS->getType()->getVectorNumElements();
+      Base = Builder.CreateVectorSplat(NumElts, Base);
+    }
     return new ICmpInst(Cond, Base,
                         ConstantExpr::getBitCast(cast<Constant>(RHS),
                                                  Base->getType()));
index 544f9a3f2e380d16e732500dd97b017b3656c8af..6cf294add7414791a6885669447296b5ef3281eb 100644 (file)
@@ -75,12 +75,10 @@ entry:
   ret i1 %cnd
 }
 
-;; TODO: vectors not yet handled
 define <2 x i1> @test_vector_base(<2 x i8*> %base, i64 %idx) {
 ; CHECK-LABEL: @test_vector_base(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, <2 x i8*> [[BASE:%.*]], i64 [[IDX:%.*]]
-; CHECK-NEXT:    [[CND:%.*]] = icmp eq <2 x i8*> [[GEP]], zeroinitializer
+; CHECK-NEXT:    [[CND:%.*]] = icmp eq <2 x i8*> [[BASE:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CND]]
 ;
 entry:
@@ -92,8 +90,9 @@ entry:
 define <2 x i1> @test_vector_index(i8* %base, <2 x i64> %idx) {
 ; CHECK-LABEL: @test_vector_index(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, i8* [[BASE:%.*]], <2 x i64> [[IDX:%.*]]
-; CHECK-NEXT:    [[CND:%.*]] = icmp eq <2 x i8*> [[GEP]], zeroinitializer
+; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i8*> undef, i8* [[BASE:%.*]], i32 0
+; CHECK-NEXT:    [[DOTSPLAT:%.*]] = shufflevector <2 x i8*> [[DOTSPLATINSERT]], <2 x i8*> undef, <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[CND:%.*]] = icmp eq <2 x i8*> [[DOTSPLAT]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CND]]
 ;
 entry:
@@ -105,8 +104,7 @@ entry:
 define <2 x i1> @test_vector_both(<2 x i8*> %base, <2 x i64> %idx) {
 ; CHECK-LABEL: @test_vector_both(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, <2 x i8*> [[BASE:%.*]], <2 x i64> [[IDX:%.*]]
-; CHECK-NEXT:    [[CND:%.*]] = icmp eq <2 x i8*> [[GEP]], zeroinitializer
+; CHECK-NEXT:    [[CND:%.*]] = icmp eq <2 x i8*> [[BASE:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CND]]
 ;
 entry: