diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -3071,16 +3071,22 @@ Constant *C; if (match(NotVal, m_AShr(m_Constant(C), m_Value(Y))) && match(C, m_Negative())) { - Constant *NewC = ConstantExpr::getNot(C); - if (C->getType()->isVectorTy()) - NewC = getSafeVectorConstantForBinop(Instruction::LShr, NewC, false); - return BinaryOperator::CreateLShr(NewC, Y); + // We matched a negative constant, so propagating undef is unsafe. + // Clamp undef elements to -1. + Type *EltTy = C->getType()->getScalarType(); + C = Constant::replaceUndefsWith(C, ConstantInt::getAllOnesValue(EltTy)); + return BinaryOperator::CreateLShr(ConstantExpr::getNot(C), Y); } // ~(C >>u Y) --> ~C >>s Y (when inverting the replicated sign bits) if (match(NotVal, m_LShr(m_Constant(C), m_Value(Y))) && - match(C, m_NonNegative())) + match(C, m_NonNegative())) { + // We matched a non-negative constant, so propagating undef is unsafe. + // Clamp undef elements to 0. + Type *EltTy = C->getType()->getScalarType(); + C = Constant::replaceUndefsWith(C, ConstantInt::getNullValue(EltTy)); return BinaryOperator::CreateAShr(ConstantExpr::getNot(C), Y); + } // ~(X + C) --> -(C + 1) - X if (match(Op0, m_Add(m_Value(X), m_Constant(C)))) diff --git a/llvm/test/Transforms/InstCombine/vector-xor.ll b/llvm/test/Transforms/InstCombine/vector-xor.ll --- a/llvm/test/Transforms/InstCombine/vector-xor.ll +++ b/llvm/test/Transforms/InstCombine/vector-xor.ll @@ -172,7 +172,7 @@ define <4 x i32> @test_v4i32_not_lshr_nonnegative_const_undef(<4 x i32> %a0) { ; CHECK-LABEL: @test_v4i32_not_lshr_nonnegative_const_undef( -; CHECK-NEXT: [[TMP1:%.*]] = ashr <4 x i32> , [[A0:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = ashr <4 x i32> , [[A0:%.*]] ; CHECK-NEXT: ret <4 x i32> [[TMP1]] ; %1 = lshr <4 x i32> , %a0