]> granicus.if.org Git - llvm/commitdiff
[InstCombine] Limit a vector demanded elts rule which was producing invalid IR.
authorPhilip Reames <listmail@philipreames.com>
Tue, 30 Apr 2019 23:09:26 +0000 (23:09 +0000)
committerPhilip Reames <listmail@philipreames.com>
Tue, 30 Apr 2019 23:09:26 +0000 (23:09 +0000)
The demanded elts rules introduced for GEPs in https://reviews.llvm.org/rL356293 replaced vector constants with undefs (by design).  It turns out that the LangRef disallows such cases when indexing structs.  The right fix is probably to relax the langref requirement, and update other passes to expect the result, but for the moment, limit the transform to avoid compiler crashes.

This should fix https://bugs.llvm.org/show_bug.cgi?id=41624.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359633 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 1d52938d1f84e377ffd9ca10a62104929e2a7ef0..42406e27e35919e4df19fae67fcac126263aa2d1 100644 (file)
@@ -1169,6 +1169,18 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,
   default: break;
 
   case Instruction::GetElementPtr: {
+    // The LangRef requires that struct geps have all constant indices.  As
+    // such, we can't convert any operand to partial undef.
+    auto mayIndexStructType = [](GetElementPtrInst &GEP) {
+      for (auto I = gep_type_begin(GEP), E = gep_type_end(GEP);
+           I != E; I++)
+        if (I.isStruct())
+          return true;;
+      return false;
+    };
+    if (mayIndexStructType(cast<GetElementPtrInst>(*I)))
+      break;
+    
     // 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
index a56152cca5972a2cbf580c81edf5e293aac369e3..3f172be3d8304ac68b2d399a95c4730ab639c99c 100644 (file)
@@ -638,3 +638,16 @@ define i32* @gep_demanded_lane_undef(i32* %base, i64 %idx) {
   %ee = extractelement <2 x i32*> %gep, i32 1
   ret i32* %ee
 }
+
+
+;; LangRef has an odd quirk around FCAs which make it illegal to use undef
+;; indices.
+define i32* @PR41624(<2 x { i32, i32 }*> %a) {
+; CHECK-LABEL: @PR41624(
+; CHECK-NEXT:   %w = getelementptr { i32, i32 }, <2 x { i32, i32 }*> %a, <2 x i64> <i64 5, i64 5>, <2 x i32> zeroinitializer
+; CHECK-NEXT:   %r = extractelement <2 x i32*> %w, i32 0
+; CHECK-NEXT:   ret i32* %r
+  %w = getelementptr { i32, i32 }, <2 x { i32, i32 }*> %a, <2 x i64> <i64 5, i64 5>, <2 x i32> zeroinitializer
+  %r = extractelement <2 x i32*> %w, i32 0
+  ret i32* %r
+}