Index: llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -1192,6 +1192,12 @@ return nullptr; } if (I->getOperand(i)->getType()->isVectorTy()) { + // Don't mess with all zeros constants. There are other combines + // that consider an all zero constant index canonical. + // FIXME: Should we skip all constant splats? + if (isa(I->getOperand(i)) && + cast(I->getOperand(i))->isNullValue()) + continue; APInt UndefEltsOp(VWidth, 0); simplifyAndSetOp(I, i, DemandedElts, UndefEltsOp); UndefElts |= UndefEltsOp; Index: llvm/test/Transforms/InstCombine/vec_demanded_elts.ll =================================================================== --- llvm/test/Transforms/InstCombine/vec_demanded_elts.ll +++ llvm/test/Transforms/InstCombine/vec_demanded_elts.ll @@ -651,3 +651,23 @@ %r = extractelement <2 x i32*> %w, i32 0 ret i32* %r } + +@global = external global [0 x i32], align 4 + +; The global here has size 0 so InstCombine would like the first index to be +; zeroinitializer, but SimplifyDemandedVectorElts was trying to turn that index into +; . SimplifyDemandedVectorElts has been told +; to leave a zeroinitializer indices alone. +define i32* @ham(<4 x i64> %arg, i64 %arg1) { +; CHECK-LABEL: @ham( +; 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> zeroinitializer, <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 +} +