diff options
author | Chris Lattner <sabre@nondot.org> | 2009-10-25 06:15:37 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-10-25 06:15:37 +0000 |
commit | d8e8fb4d6470d255a53131f95923758b02b1acb8 (patch) | |
tree | d088f3121be71387f9a19599ef8d626c2b973633 /llvm/lib/Analysis/ConstantFolding.cpp | |
parent | 9d051246eb2fa86e625334c9b633f18559a9e0ce (diff) | |
download | bcm5719-llvm-d8e8fb4d6470d255a53131f95923758b02b1acb8.tar.gz bcm5719-llvm-d8e8fb4d6470d255a53131f95923758b02b1acb8.zip |
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> <i128 85174437667405312423031577302488055808> to <2 x double>), <2 x double> <double 3.000000e+00, double 4.000000e+00>), <2 x double> <double 1.000000e+00, double 2.000000e+00>), 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> <i128 85174437667405312423031577302488055808> to <2 x double>), <2 x double> <double 3.000000e+00, double 4.000000e+00>), <2 x double> <double 1.000000e+00, double 2.000000e+00>), i32 1), 1 ; <%0> [#uses=1]
ret %0 %mrv6
}
llvm-svn: 85040
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 8bb3673195d..33a5792796f 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) { - // If this is a bitcast from constant vector -> vector, fold it. - ConstantVector *CV = dyn_cast<ConstantVector>(C); - if (CV == 0) - return ConstantExpr::getBitCast(C, DestTy); + // This only handles casts to vectors currently. const VectorType *DestVTy = dyn_cast<VectorType>(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<ConstantFP>(C) || isa<ConstantInt>(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<ConstantVector>(C); + if (CV == 0) + return ConstantExpr::getBitCast(C, DestTy); + // If the element types match, VMCore can fold it. unsigned NumDstElt = DestVTy->getNumElements(); unsigned NumSrcElt = CV->getNumOperands(); |