diff options
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 40 | ||||
-rw-r--r-- | test/Transforms/InstCombine/bitcast-vec-uniform.ll | 14 | ||||
-rw-r--r-- | test/Transforms/InstCombine/fold-vector-select.ll | 13 |
3 files changed, 67 insertions, 0 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index f2129c08d2..0ec343f07d 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -42,6 +42,10 @@ using namespace llvm; /// input vector constant are all simple integer or FP values. static Constant *BitCastConstantVector(ConstantVector *CV, const VectorType *DstTy) { + + if (CV->isAllOnesValue()) return Constant::getAllOnesValue(DstTy); + if (CV->isNullValue()) return Constant::getNullValue(DstTy); + // If this cast changes element count then we can't handle it here: // doing so requires endianness information. This should be handled by // Analysis/ConstantFolding.cpp @@ -689,6 +693,42 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, if (ConstantInt *CB = dyn_cast<ConstantInt>(Cond)) return CB->getZExtValue() ? V1 : V2; + // Check for zero aggregate and ConstantVector of zeros + if (Cond->isNullValue()) return V2; + + if (ConstantVector* CondV = dyn_cast<ConstantVector>(Cond)) { + + if (CondV->isAllOnesValue()) return V1; + + const VectorType *VTy = cast<VectorType>(V1->getType()); + ConstantVector *CP1 = dyn_cast<ConstantVector>(V1); + ConstantVector *CP2 = dyn_cast<ConstantVector>(V2); + + if ((CP1 || isa<ConstantAggregateZero>(V1)) && + (CP2 || isa<ConstantAggregateZero>(V2))) { + + // Find the element type of the returned vector + const Type *EltTy = VTy->getElementType(); + unsigned NumElem = VTy->getNumElements(); + std::vector<Constant*> Res(NumElem); + + bool Valid = true; + for (unsigned i = 0; i < NumElem; ++i) { + ConstantInt* c = dyn_cast<ConstantInt>(CondV->getOperand(i)); + if (!c) { + Valid = false; + break; + } + Constant *C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + Constant *C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res[i] = c->getZExtValue() ? C1 : C2; + } + // If we were able to build the vector, return it + if (Valid) return ConstantVector::get(Res); + } + } + + if (isa<UndefValue>(V1)) return V2; if (isa<UndefValue>(V2)) return V1; if (isa<UndefValue>(Cond)) return V1; diff --git a/test/Transforms/InstCombine/bitcast-vec-uniform.ll b/test/Transforms/InstCombine/bitcast-vec-uniform.ll new file mode 100644 index 0000000000..1fba163269 --- /dev/null +++ b/test/Transforms/InstCombine/bitcast-vec-uniform.ll @@ -0,0 +1,14 @@ +; RUN: opt < %s -instcombine -S | not grep bitcast + +define <4 x i32> @a(<1 x i64> %y) { + %c = bitcast <2 x i64> <i64 0, i64 0> to <4 x i32> + ret <4 x i32> %c +} + +define <4 x i32> @b(<1 x i64> %y) { + %c = bitcast <2 x i64> <i64 -1, i64 -1> to <4 x i32> + ret <4 x i32> %c +} + + + diff --git a/test/Transforms/InstCombine/fold-vector-select.ll b/test/Transforms/InstCombine/fold-vector-select.ll new file mode 100644 index 0000000000..3f22522a6c --- /dev/null +++ b/test/Transforms/InstCombine/fold-vector-select.ll @@ -0,0 +1,13 @@ +; RUN: opt < %s -instcombine -S | not grep select + +define void @foo(<4 x i32> *%A, <4 x i32> *%B, <4 x i32> *%C, <4 x i32> *%D) { + %r = select <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> <i32 1, i32 2, i32 3, i32 4>, <4 x i32> zeroinitializer + %g = select <4 x i1> <i1 false, i1 false, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 6, i32 9, i32 1> + %b = select <4 x i1> <i1 false, i1 true, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 7, i32 1, i32 4, i32 9> + %a = select <4 x i1> zeroinitializer, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 8, i32 5> + store <4 x i32> %r, <4 x i32>* %A + store <4 x i32> %g, <4 x i32>* %B + store <4 x i32> %b, <4 x i32>* %C + store <4 x i32> %a, <4 x i32>* %D + ret void +} |