[InstCombine] Support vectors in icmp of GEP fold
authorNikita Popov <npopov@redhat.com>
Mon, 2 Jan 2023 14:28:10 +0000 (15:28 +0100)
committerNikita Popov <npopov@redhat.com>
Mon, 2 Jan 2023 14:29:13 +0000 (15:29 +0100)
EmitGEPOffset() supports vector GEPs nowadays, so we don't need
any further code changes.

compare_gep_with_base_vector1 shows a weakness in folding the
resulting comparison if an index splat has to be performed.

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/opaque-ptr.ll

index 9801c72..1c560c7 100644 (file)
@@ -740,9 +740,7 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
     RHS = RHS->stripPointerCasts();
 
   Value *PtrBase = GEPLHS->getOperand(0);
-  // FIXME: Support vector pointer GEPs.
-  if (PtrBase == RHS && GEPLHS->isInBounds() &&
-      !GEPLHS->getType()->isVectorTy()) {
+  if (PtrBase == RHS && GEPLHS->isInBounds()) {
     // ((gep Ptr, OFFSET) cmp Ptr)   ---> (OFFSET cmp 0).
     Value *Offset = EmitGEPOffset(GEPLHS);
     return new ICmpInst(ICmpInst::getSignedPredicate(Cond), Offset,
index a1e67e5..da69f7d 100644 (file)
@@ -334,8 +334,10 @@ define i1 @compare_gep_with_base(ptr %p, i64 %idx) {
 
 define <2 x i1> @compare_gep_with_base_vector1(<2 x ptr> %p, i64 %idx) {
 ; CHECK-LABEL: @compare_gep_with_base_vector1(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, <2 x ptr> [[P:%.*]], i64 [[IDX:%.*]]
-; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x ptr> [[GEP]], [[P]]
+; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[IDX:%.*]], i64 0
+; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0>
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer
+; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %gep = getelementptr inbounds i32, <2 x ptr> %p, i64 %idx
@@ -345,8 +347,7 @@ define <2 x i1> @compare_gep_with_base_vector1(<2 x ptr> %p, i64 %idx) {
 
 define <2 x i1> @compare_gep_with_base_vector2(<2 x ptr> %p, <2 x i64> %idx) {
 ; CHECK-LABEL: @compare_gep_with_base_vector2(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, <2 x ptr> [[P:%.*]], <2 x i64> [[IDX:%.*]]
-; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x ptr> [[GEP]], [[P]]
+; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i64> [[IDX:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %gep = getelementptr inbounds i32, <2 x ptr> %p, <2 x i64> %idx