From ab789db0b9cdf0e4c0b5ac2253ab8ec61cd0a7e4 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Fri, 21 Jan 2011 02:30:43 +0000 Subject: [PATCH] Don't try to pull vector bitcasts that change the number of elements through a select. A vector select is pairwise on each element so we'd need a new condition with the right number of elements to select on. Fixes PR8994. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123963 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstructionCombining.cpp | 20 +++++++++++++++++--- test/Transforms/InstCombine/select.ll | 11 +++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index ab019a1362..2e908e73f9 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -455,8 +455,9 @@ Value *InstCombiner::dyn_castFNegVal(Value *V) const { static Value *FoldOperationIntoSelectOperand(Instruction &I, Value *SO, InstCombiner *IC) { - if (CastInst *CI = dyn_cast(&I)) + if (CastInst *CI = dyn_cast(&I)) { return IC->Builder->CreateCast(CI->getOpcode(), SO, I.getType()); + } // Figure out if the constant is the left or the right argument. bool ConstIsRHS = isa(I.getOperand(1)); @@ -498,11 +499,24 @@ Instruction *InstCombiner::FoldOpIntoSelect(Instruction &Op, SelectInst *SI) { // Bool selects with constant operands can be folded to logical ops. if (SI->getType()->isIntegerTy(1)) return 0; + // If it's a bitcast involving vectors, make sure it has the same number of + // elements on both sides. + if (BitCastInst *BC = dyn_cast(&Op)) { + const VectorType *DestTy = dyn_cast(BC->getDestTy()); + const VectorType *SrcTy = dyn_cast(BC->getSrcTy()); + + // Verify that either both or neither are vectors. + if ((SrcTy == NULL) != (DestTy == NULL)) return 0; + // If vectors, verify that they have the same number of elements. + if (SrcTy && SrcTy->getNumElements() != DestTy->getNumElements()) + return 0; + } + Value *SelectTrueVal = FoldOperationIntoSelectOperand(Op, TV, this); Value *SelectFalseVal = FoldOperationIntoSelectOperand(Op, FV, this); - return SelectInst::Create(SI->getCondition(), SelectTrueVal, - SelectFalseVal); + return SelectInst::Create(SI->getCondition(), + SelectTrueVal, SelectFalseVal); } return 0; } diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index 6633564c2b..54cfc467cc 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -689,3 +689,14 @@ define i64 @test50(i32 %a) nounwind { ; CHECK-NEXT: %min = select i1 %is_a_nonpositive, i64 %a_ext, i64 2 ; CHECK-NEXT: ret i64 %min } + +; PR8994 + +; Theis select instruction can't be eliminated because trying to do so would +; change the number of vector elements. This used to assert. +define i48 @test51(<3 x i1> %icmp, <3 x i16> %tmp) { + %select = select <3 x i1> %icmp, <3 x i16> zeroinitializer, <3 x i16> %tmp +; CHECK: select <3 x i1> + %tmp2 = bitcast <3 x i16> %select to i48 + ret i48 %tmp2 +} -- 2.11.4.GIT