[PATCH] D60600: [InstCombine] Fix a vector-of-pointers instcombine undef bug.

Neil Henning via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 23 03:41:23 PDT 2019


sheredom updated this revision to Diff 196205.
sheredom added a comment.

Fix some review comments by @spatel


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60600/new/

https://reviews.llvm.org/D60600

Files:
  lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  test/Transforms/InstCombine/vec_demanded_elts.ll


Index: test/Transforms/InstCombine/vec_demanded_elts.ll
===================================================================
--- test/Transforms/InstCombine/vec_demanded_elts.ll
+++ test/Transforms/InstCombine/vec_demanded_elts.ll
@@ -638,3 +638,25 @@
   %ee = extractelement <2 x i32*> %gep, i32 1
   ret i32* %ee
 }
+
+%foo = type { float, i8 }
+
+define void @gep_vector_of_pointers_to_struct(float* %out, [2 x %foo]* %in) {
+; CHECK-LABEL: @gep_vector_of_pointers_to_struct(
+; CHECK-NEXT:    [[B:%.*]] = insertelement <2 x [2 x %foo]*> undef, [2 x %foo]* [[IN:%.*]], i32 1
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [2 x %foo], <2 x [2 x %foo]*> [[B]], <2 x i64> <i64 undef, i64 0>, <2 x i64> <i64 undef, i64 1>, <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float*> [[GEP]] to <2 x i32*>
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32*> [[BC]], i64 1
+; CHECK-NEXT:    [[LOAD1:%.*]] = load i32, i32* [[TMP1]], align 4
+; CHECK-NEXT:    [[TMP2:%.*]] = bitcast float* [[OUT:%.*]] to i32*
+; CHECK-NEXT:    store i32 [[LOAD1]], i32* [[TMP2]], align 4
+; CHECK-NEXT:    ret void
+;
+  %a = insertelement <2 x [2 x %foo]*> undef, [2 x %foo]* %in, i32 0
+  %b = insertelement <2 x [2 x %foo]*> %a, [2 x %foo]* %in, i32 1
+  %gep = getelementptr [2 x %foo], <2 x [2 x %foo]*> %b, <2 x i32> zeroinitializer, <2 x i32> <i32 0, i32 1>, <2 x i32> zeroinitializer
+  %extract = extractelement <2 x float*> %gep, i64 1
+  %load = load float, float* %extract, align 4
+  store float %load, float* %out
+  ret void
+}
Index: lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1173,18 +1173,35 @@
     // 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. 
-    for (unsigned i = 0; i < I->getNumOperands(); i++) {
-      if (isa<UndefValue>(I->getOperand(i))) {
+    // index results in undef.
+
+    auto simplifyGEPOperand = [&](unsigned Idx, bool IsIndexStruct) {
+      if (isa<UndefValue>(I->getOperand(Idx))) {
         // If the entire vector is undefined, just return this info.
         UndefElts = EltMask;
-        return nullptr;
+        return true;
       }
-      if (I->getOperand(i)->getType()->isVectorTy()) {
+
+      if (!IsIndexStruct && I->getOperand(Idx)->getType()->isVectorTy()) {
+        // If we have a vector of indices into a struct element of the GEP, and
+        // change a single element of this into an undef while preserving the
+        // others, that breaks the guarantee that each index of a
+        // vector-of-pointers into a struct will have the same index.
         APInt UndefEltsOp(VWidth, 0);
-        simplifyAndSetOp(I, i, DemandedElts, UndefEltsOp);
+        simplifyAndSetOp(I, Idx, DemandedElts, UndefEltsOp);
         UndefElts |= UndefEltsOp;
       }
+
+      return false;
+    };
+
+    if (simplifyGEPOperand(0, false))
+      return nullptr;
+
+    gep_type_iterator GTI = gep_type_begin(cast<GetElementPtrInst>(I));
+    for (unsigned Idx = 1; Idx < I->getNumOperands(); Idx++, GTI++) {
+      if (simplifyGEPOperand(Idx, GTI.isStruct()))
+        return nullptr;
     }
 
     break;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60600.196205.patch
Type: text/x-patch
Size: 3483 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190423/365793d5/attachment.bin>


More information about the llvm-commits mailing list