From d8e8fb4d6470d255a53131f95923758b02b1acb8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 25 Oct 2009 06:15:37 +0000 Subject: [PATCH] Teach FoldBitCast to be able to handle bitcasts from (e.g.) i128 -> <4 x float>. This allows us to simplify this: union vec2d { double e[2]; double v __attribute__((vector_size(16))); }; typedef union vec2d vec2d; static vec2d a={{1,2}}, b={{3,4}}; vec2d foo () { return (vec2d){ .v = a.v + b.v * (vec2d){{5,5}}.v }; } down to: define %0 @foo() nounwind ssp { entry: %mrv5 = insertvalue %0 undef, double 1.600000e+01, 0 ; <%0> [#uses=1] %mrv6 = insertvalue %0 %mrv5, double 2.200000e+01, 1 ; <%0> [#uses=1] ret %0 %mrv6 } instead of: define %0 @foo() nounwind ssp { entry: %mrv5 = insertvalue %0 undef, double extractelement (<2 x double> fadd (<2 x double> fmul (<2 x double> bitcast (<1 x i128> to <2 x double>), <2 x double> ), <2 x double> ), i32 0), 0 ; <%0> [#uses=1] %mrv6 = insertvalue %0 %mrv5, double extractelement (<2 x double> fadd (<2 x double> fmul (<2 x double> bitcast (<1 x i128> to <2 x double>), <2 x double> ), <2 x double> ), i32 1), 1 ; <%0> [#uses=1] ret %0 %mrv6 } llvm-svn: 85040 --- llvm/lib/Analysis/ConstantFolding.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 8bb3673195df..33a5792796f2 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -44,15 +44,24 @@ using namespace llvm; /// ConstantExpr if unfoldable. static Constant *FoldBitCast(Constant *C, const Type *DestTy, const TargetData &TD) { + + // This only handles casts to vectors currently. + const VectorType *DestVTy = dyn_cast(DestTy); + if (DestVTy == 0) + return ConstantExpr::getBitCast(C, DestTy); + + // If this is a scalar -> vector cast, convert the input into a <1 x scalar> + // vector so the code below can handle it uniformly. + if (isa(C) || isa(C)) { + Constant *Ops = C; // don't take the address of C! + return FoldBitCast(ConstantVector::get(&Ops, 1), DestTy, TD); + } + // If this is a bitcast from constant vector -> vector, fold it. ConstantVector *CV = dyn_cast(C); if (CV == 0) return ConstantExpr::getBitCast(C, DestTy); - const VectorType *DestVTy = dyn_cast(DestTy); - if (DestVTy == 0) - return ConstantExpr::getBitCast(C, DestTy); - // If the element types match, VMCore can fold it. unsigned NumDstElt = DestVTy->getNumElements(); unsigned NumSrcElt = CV->getNumOperands();