Skip to content

Commit

Permalink
[InstCombine] Use m_Zero instead of isNullValue() when checking if a …
Browse files Browse the repository at this point in the history
…GEP index is all zeroes to prevent an infinite loop.

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

llvm-svn: 373000
  • Loading branch information
topperc committed Sep 26, 2019
1 parent adc1830 commit 46721bb
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
17 changes: 17 additions & 0 deletions llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

0 comments on commit 46721bb

Please sign in to comment.