[InstCombine] remove incorrect gep(x, undef) -> undef optimization
authorNuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Sun, 30 Jan 2022 11:34:32 +0000 (11:34 +0000)
committerNuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Sun, 30 Jan 2022 11:34:32 +0000 (11:34 +0000)
gep(x, undef) carries the provenance of x, so we can't replace it with any
pointer like undef.
This leaves room for improvement for the poison case, but that's currently
not possible as the demanded bits API doesn't distinguish between undef &
poison bits.

Fixes #44790

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/test/Transforms/InstCombine/vec_demanded_elts-inseltpoison.ll
llvm/test/Transforms/InstCombine/vec_demanded_elts.ll

index 71a5ae2..3f064cf 100644 (file)
@@ -1219,7 +1219,7 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
       for (auto I = gep_type_begin(GEP), E = gep_type_end(GEP);
            I != E; I++)
         if (I.isStruct())
-          return true;;
+          return true;
       return false;
     };
     if (mayIndexStructType(cast<GetElementPtrInst>(*I)))
@@ -1228,10 +1228,11 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
     // Conservatively track the demanded elements back through any vector
     // operands we may have.  We know there must be at least one, or we
     // wouldn't have a vector result to get here. Note that we intentionally
-    // merge the undef bits here since gepping with either an undef base or
-    // index results in undef.
+    // merge the undef bits here since gepping with either an poison base or
+    // index results in poison.
     for (unsigned i = 0; i < I->getNumOperands(); i++) {
-      if (match(I->getOperand(i), m_Undef())) {
+      if (i == 0 ? match(I->getOperand(i), m_Undef())
+                 : match(I->getOperand(i), m_Poison())) {
         // If the entire vector is undefined, just return this info.
         UndefElts = EltMask;
         return nullptr;
@@ -1239,7 +1240,11 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
       if (I->getOperand(i)->getType()->isVectorTy()) {
         APInt UndefEltsOp(VWidth, 0);
         simplifyAndSetOp(I, i, DemandedElts, UndefEltsOp);
-        UndefElts |= UndefEltsOp;
+        // gep(x, undef) is not undef, so skip considering idx ops here
+        // Note that we could propagate poison, but we can't distinguish between
+        // undef & poison bits ATM
+        if (i == 0)
+          UndefElts |= UndefEltsOp;
       }
     }
 
index ad84f65..1c0cb17 100644 (file)
@@ -614,7 +614,10 @@ define i32* @gep_splat_both(i32* %base, i64 %idx) {
 
 define <2 x i32*> @gep_all_lanes_undef(i32* %base, i64 %idx) {;
 ; CHECK-LABEL: @gep_all_lanes_undef(
-; CHECK-NEXT:    ret <2 x i32*> undef
+; CHECK-NEXT:    [[BASEVEC:%.*]] = insertelement <2 x i32*> poison, i32* [[BASE:%.*]], i64 0
+; CHECK-NEXT:    [[IDXVEC:%.*]] = insertelement <2 x i64> poison, i64 [[IDX:%.*]], i64 1
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, <2 x i32*> [[BASEVEC]], <2 x i64> [[IDXVEC]]
+; CHECK-NEXT:    ret <2 x i32*> [[GEP]]
 ;
   %basevec = insertelement <2 x i32*> poison, i32* %base, i32 0
   %idxvec = insertelement <2 x i64> poison, i64 %idx, i32 1
index d64869f..17b3bdf 100644 (file)
@@ -614,7 +614,10 @@ define i32* @gep_splat_both(i32* %base, i64 %idx) {
 
 define <2 x i32*> @gep_all_lanes_undef(i32* %base, i64 %idx) {;
 ; CHECK-LABEL: @gep_all_lanes_undef(
-; CHECK-NEXT:    ret <2 x i32*> undef
+; CHECK-NEXT:    [[BASEVEC:%.*]] = insertelement <2 x i32*> undef, i32* [[BASE:%.*]], i64 0
+; CHECK-NEXT:    [[IDXVEC:%.*]] = insertelement <2 x i64> undef, i64 [[IDX:%.*]], i64 1
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, <2 x i32*> [[BASEVEC]], <2 x i64> [[IDXVEC]]
+; CHECK-NEXT:    ret <2 x i32*> [[GEP]]
 ;
   %basevec = insertelement <2 x i32*> undef, i32* %base, i32 0
   %idxvec = insertelement <2 x i64> undef, i64 %idx, i32 1