summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2015-05-11 06:37:03 +0000
committerHal Finkel <hfinkel@anl.gov>2015-05-11 06:37:03 +0000
commitf0d68d788b7ff79ffdd315db3b57b6c4e0f0de2b (patch)
tree5dd781f583f2561cd14ea158d5780dc8768ae5e8 /llvm/lib
parent5b9ee1ba7e4d7d5a3ae0d6233b4cf26aa6c72647 (diff)
downloadbcm5719-llvm-f0d68d788b7ff79ffdd315db3b57b6c4e0f0de2b.tar.gz
bcm5719-llvm-f0d68d788b7ff79ffdd315db3b57b6c4e0f0de2b.zip
[InstCombine/PowerPC] Fix single-precision QPX load/store replacement
The QPX single-precision load/store intrinsics have implied truncation/extension from/to the declared value type of <4 x double> to the memory type of <4 x float>. When we can prove the alignment of the pointer argument, and thus replace the intrinsic with a regular load or store, we need to load or store the correct data type (<4 x float>) instead of (<4 x double>). llvm-svn: 236973
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp15
1 files changed, 10 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 20c5a897b96..cae611f21b2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -624,9 +624,12 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
// Turn PPC QPX qvlfs -> load if the pointer is known aligned.
if (getOrEnforceKnownAlignment(II->getArgOperand(0), 16, DL, II, AC, DT) >=
16) {
+ Type *VTy = VectorType::get(Builder->getFloatTy(),
+ II->getType()->getVectorNumElements());
Value *Ptr = Builder->CreateBitCast(II->getArgOperand(0),
- PointerType::getUnqual(II->getType()));
- return new LoadInst(Ptr);
+ PointerType::getUnqual(VTy));
+ Value *Load = Builder->CreateLoad(Ptr);
+ return new FPExtInst(Load, II->getType());
}
break;
case Intrinsic::ppc_qpx_qvlfd:
@@ -642,10 +645,12 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
// Turn PPC QPX qvstfs -> store if the pointer is known aligned.
if (getOrEnforceKnownAlignment(II->getArgOperand(1), 16, DL, II, AC, DT) >=
16) {
- Type *OpPtrTy =
- PointerType::getUnqual(II->getArgOperand(0)->getType());
+ Type *VTy = VectorType::get(Builder->getFloatTy(),
+ II->getArgOperand(0)->getType()->getVectorNumElements());
+ Value *TOp = Builder->CreateFPTrunc(II->getArgOperand(0), VTy);
+ Type *OpPtrTy = PointerType::getUnqual(VTy);
Value *Ptr = Builder->CreateBitCast(II->getArgOperand(1), OpPtrTy);
- return new StoreInst(II->getArgOperand(0), Ptr);
+ return new StoreInst(TOp, Ptr);
}
break;
case Intrinsic::ppc_qpx_qvstfd:
OpenPOWER on IntegriCloud