diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1667,7 +1667,7 @@ // 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(*I) || !cast(*I)->isNullValue()) { + if (!isa(*I) || !match(I->get(), m_Zero())) { *I = Constant::getNullValue(NewIndexType); MadeChange = true; } diff --git a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll --- a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll +++ b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll @@ -651,3 +651,20 @@ %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> , <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 +}