]> granicus.if.org Git - llvm/commitdiff
[InstCombine] Use m_Zero instead of isNullValue() when checking if a GEP index is...
authorCraig Topper <craig.topper@intel.com>
Thu, 26 Sep 2019 17:20:50 +0000 (17:20 +0000)
committerCraig Topper <craig.topper@intel.com>
Thu, 26 Sep 2019 17:20:50 +0000 (17:20 +0000)
The test case here previously infinite looped. Only one element from the GEP is used so SimplifyDemandedVectorElts would replace the other lanes in each index with undef leading to the first index being <0, undef, undef, undef>. But there's a GEP transform that tries to replace an index into a 0 sized type with a zero index. But the zero index check only works on ConstantInt 0 or ConstantAggregateZero so it would turn the index back to zeroinitializer. Resulting in a loop.

The fix is to use m_Zero() to allow a vector of zeroes and undefs.

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

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

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

index 7577498099690f7edb021e50fea4d3c849599a12..ecb486c544e03a9941196d5b602ae2b98834fd40 100644 (file)
@@ -1667,7 +1667,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
     // to an index of zero, so replace it with zero if it is not zero already.
     Type *EltTy = GTI.getIndexedType();
     if (EltTy->isSized() && DL.getTypeAllocSize(EltTy) == 0)
-      if (!isa<Constant>(*I) || !cast<Constant>(*I)->isNullValue()) {
+      if (!isa<Constant>(*I) || !match(I->get(), m_Zero())) {
         *I = Constant::getNullValue(NewIndexType);
         MadeChange = true;
       }
index 3f172be3d8304ac68b2d399a95c4730ab639c99c..164061de5112c71418a782beb0c2c0bac4a9c4a8 100644 (file)
@@ -651,3 +651,20 @@ define i32* @PR41624(<2 x { i32, i32 }*> %a) {
   %r = extractelement <2 x i32*> %w, i32 0
   ret i32* %r
 }
+
+@global = external global [0 x i32], align 4
+
+; Make sure we don't get stuck in a loop turning the zeroinitializer into
+; <0, undef, undef, undef> and then changing it back.
+define i32* @zero_sized_type_extract(<4 x i64> %arg, i64 %arg1) {
+; CHECK-LABEL: @zero_sized_type_extract(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    [[TMP:%.*]] = getelementptr inbounds [0 x i32], <4 x [0 x i32]*> <[0 x i32]* @global, [0 x i32]* undef, [0 x i32]* undef, [0 x i32]* undef>, <4 x i64> <i64 0, i64 undef, i64 undef, i64 undef>, <4 x i64> [[ARG:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i32*> [[TMP]], i64 0
+; CHECK-NEXT:    ret i32* [[TMP2]]
+;
+bb:
+  %tmp = getelementptr inbounds [0 x i32], <4 x [0 x i32]*> <[0 x i32]* @global, [0 x i32]* @global, [0 x i32]* @global, [0 x i32]* @global>, <4 x i64> zeroinitializer, <4 x i64> %arg
+  %tmp2 = extractelement <4 x i32*> %tmp, i64 0
+  ret i32* %tmp2
+}