summaryrefslogtreecommitdiff
path: root/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-10-25 06:15:37 +0000
committerChris Lattner <sabre@nondot.org>2009-10-25 06:15:37 +0000
commit93798daa3ecbfb29624052d3e54d2404ab65897a (patch)
tree7bcda45ed58d1eb64dd41dc179514ee698283a21 /lib/Analysis/ConstantFolding.cpp
parent6333c3959b7e3e43930ab523f0657791e9eb5d48 (diff)
downloadllvm-93798daa3ecbfb29624052d3e54d2404ab65897a.tar.gz
llvm-93798daa3ecbfb29624052d3e54d2404ab65897a.tar.bz2
llvm-93798daa3ecbfb29624052d3e54d2404ab65897a.tar.xz
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 } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85040 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ConstantFolding.cpp')
-rw-r--r--lib/Analysis/ConstantFolding.cpp17
1 files changed, 13 insertions, 4 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 8bb3673195..33a5792796 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/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();