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 @@ -924,6 +924,12 @@ return ConstantExpr::getNeg(CV); } + // Negate integer vector splats. + if (auto *CV = dyn_cast(V)) + if (CV->getType()->isVectorTy() && + CV->getType()->getScalarType()->isIntegerTy() && CV->getSplatValue()) + return ConstantExpr::getNeg(CV); + return nullptr; } diff --git a/llvm/test/Transforms/InstCombine/sub.ll b/llvm/test/Transforms/InstCombine/sub.ll --- a/llvm/test/Transforms/InstCombine/sub.ll +++ b/llvm/test/Transforms/InstCombine/sub.ll @@ -839,11 +839,9 @@ ret <2 x i32> %sub } -; FIXME: We're not giving this new 'add' a nsw flag as in the fixed-length case -; above. We need to be able catch the splat with dyn_castNegVal. define @test44scalablevec( %x) { ; CHECK-LABEL: @test44scalablevec( -; CHECK-NEXT: [[SUB:%.*]] = add [[X:%.*]], shufflevector ( insertelement ( undef, i32 -32768, i32 0), undef, zeroinitializer) +; CHECK-NEXT: [[SUB:%.*]] = add nsw [[X:%.*]], shufflevector ( insertelement ( undef, i32 -32768, i32 0), undef, zeroinitializer) ; CHECK-NEXT: ret [[SUB]] ; %sub = sub nsw %x, shufflevector ( insertelement ( undef, i32 32768, i32 0), undef, zeroinitializer)