From eb7d69d49a0f5d68e80b53f411b559d05b46c8be Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Wed, 14 May 2014 09:05:09 +0000 Subject: [PATCH] Fix the case when reordering shuffle and binop produces a constant. This resolves PR19737. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208762 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstructionCombining.cpp | 26 +++++++++++----------- test/Transforms/InstCombine/vec_shuffle.ll | 11 +++++++++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 8c0a249aee1..4c36887f628 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1085,18 +1085,18 @@ Value *InstCombiner::Descale(Value *Val, APInt Scale, bool &NoSignedWrap) { /// \brief Creates node of binary operation with the same attributes as the /// specified one but with other operands. -static BinaryOperator *CreateBinOpAsGiven(BinaryOperator &Inst, Value *LHS, - Value *RHS, - InstCombiner::BuilderTy *B) { - BinaryOperator *NewBO = cast(B->CreateBinOp(Inst.getOpcode(), - LHS, RHS)); - if (isa(NewBO)) { - NewBO->setHasNoSignedWrap(Inst.hasNoSignedWrap()); - NewBO->setHasNoUnsignedWrap(Inst.hasNoUnsignedWrap()); +static Value *CreateBinOpAsGiven(BinaryOperator &Inst, Value *LHS, Value *RHS, + InstCombiner::BuilderTy *B) { + Value *BORes = B->CreateBinOp(Inst.getOpcode(), LHS, RHS); + if (BinaryOperator *NewBO = dyn_cast(BORes)) { + if (isa(NewBO)) { + NewBO->setHasNoSignedWrap(Inst.hasNoSignedWrap()); + NewBO->setHasNoUnsignedWrap(Inst.hasNoUnsignedWrap()); + } + if (isa(NewBO)) + NewBO->setIsExact(Inst.isExact()); } - if (isa(NewBO)) - NewBO->setIsExact(Inst.isExact()); - return NewBO; + return BORes; } /// \brief Makes transformation of binary operation specific for vector types. @@ -1122,7 +1122,7 @@ Value *InstCombiner::SimplifyVectorOp(BinaryOperator &Inst) { isa(RShuf->getOperand(1)) && LShuf->getOperand(0)->getType() == RShuf->getOperand(0)->getType() && LShuf->getMask() == RShuf->getMask()) { - BinaryOperator *NewBO = CreateBinOpAsGiven(Inst, LShuf->getOperand(0), + Value *NewBO = CreateBinOpAsGiven(Inst, LShuf->getOperand(0), RShuf->getOperand(0), Builder); Value *Res = Builder->CreateShuffleVector(NewBO, UndefValue::get(NewBO->getType()), LShuf->getMask()); @@ -1168,7 +1168,7 @@ Value *InstCombiner::SimplifyVectorOp(BinaryOperator &Inst) { NewLHS = Shuffle->getOperand(0); NewRHS = C2; } - BinaryOperator *NewBO = CreateBinOpAsGiven(Inst, NewLHS, NewRHS, Builder); + Value *NewBO = CreateBinOpAsGiven(Inst, NewLHS, NewRHS, Builder); Value *Res = Builder->CreateShuffleVector(NewBO, UndefValue::get(Inst.getType()), Shuffle->getMask()); return Res; diff --git a/test/Transforms/InstCombine/vec_shuffle.ll b/test/Transforms/InstCombine/vec_shuffle.ll index 2e6f787f833..fc0f8bd0aa9 100644 --- a/test/Transforms/InstCombine/vec_shuffle.ll +++ b/test/Transforms/InstCombine/vec_shuffle.ll @@ -394,3 +394,14 @@ define <8 x i8> @pr19730(<16 x i8> %in0) { %shuffle1 = shufflevector <8 x i8> %shuffle, <8 x i8> undef, <8 x i32> ret <8 x i8> %shuffle1 } + +define i32 @pr19737(<4 x i32> %in0) { +; CHECK-LABEL: @pr19737( +; CHECK: [[VAR:%[a-zA-Z0-9.]+]] = extractelement <4 x i32> %in0, i32 0 +; CHECK: ret i32 [[VAR]] + %shuffle.i = shufflevector <4 x i32> zeroinitializer, <4 x i32> %in0, <4 x i32> + %neg.i = xor <4 x i32> %shuffle.i, + %and.i = and <4 x i32> %in0, %neg.i + %rv = extractelement <4 x i32> %and.i, i32 0 + ret i32 %rv +} -- 2.11.0