teach libanalysis to simplify vector loads with bitcast sources. This
implements something out of Target/README.txt producing:
_foo: ## @foo
movl 4(%esp), %eax
movapd LCPI1_0, %xmm0
movapd %xmm0, (%eax)
ret $4
instead of:
_foo: ## @foo
movl 4(%esp), %eax
movapd _b, %xmm0
mulpd LCPI1_0, %xmm0
addpd _a, %xmm0
movapd %xmm0, (%eax)
ret $4
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84942 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 3030504..214caeb 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -210,24 +210,30 @@
static Constant *FoldReinterpretLoadFromConstPtr(Constant *C,
const TargetData &TD) {
- const Type *InitializerTy = cast<PointerType>(C->getType())->getElementType();
- const IntegerType *IntType = dyn_cast<IntegerType>(InitializerTy);
+ const Type *LoadTy = cast<PointerType>(C->getType())->getElementType();
+ const IntegerType *IntType = dyn_cast<IntegerType>(LoadTy);
// If this isn't an integer load we can't fold it directly.
if (!IntType) {
// If this is a float/double load, we can try folding it as an int32/64 load
- // and then bitcast the result. This can be useful for union cases.
+ // and then bitcast the result. This can be useful for union cases. Note
+ // that address spaces don't matter here since we're not going to result in
+ // an actual new load.
const Type *MapTy;
- if (InitializerTy->isFloatTy())
+ if (LoadTy->isFloatTy())
MapTy = Type::getInt32PtrTy(C->getContext());
- else if (InitializerTy->isDoubleTy())
+ else if (LoadTy->isDoubleTy())
MapTy = Type::getInt64PtrTy(C->getContext());
- else
+ else if (isa<VectorType>(LoadTy)) {
+ MapTy = IntegerType::get(C->getContext(),
+ TD.getTypeAllocSizeInBits(LoadTy));
+ MapTy = PointerType::getUnqual(MapTy);
+ } else
return 0;
C = ConstantExpr::getBitCast(C, MapTy);
if (Constant *Res = FoldReinterpretLoadFromConstPtr(C, TD))
- return ConstantExpr::getBitCast(Res, InitializerTy);
+ return ConstantExpr::getBitCast(Res, LoadTy);
return 0;
}