From cdd4737be863e9b3679874ff45f247bebafb3c87 Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Mon, 11 May 2015 06:37:03 +0000 Subject: [PATCH] [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>). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236973 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineCalls.cpp | 15 ++++++++++----- test/Transforms/InstCombine/aligned-qpx.ll | 3 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 20c5a897b96..cae611f21b2 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/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: diff --git a/test/Transforms/InstCombine/aligned-qpx.ll b/test/Transforms/InstCombine/aligned-qpx.ll index e303ddd17d5..e9710df5670 100644 --- a/test/Transforms/InstCombine/aligned-qpx.ll +++ b/test/Transforms/InstCombine/aligned-qpx.ll @@ -28,6 +28,7 @@ entry: ; CHECK-LABEL: @test1a ; CHECK-NOT: @llvm.ppc.qpx.qvlfs +; CHECK-NOT: load <4 x double> ; CHECK: ret <4 x double> %v0 = load <4 x float>, <4 x float>* %h, align 8 @@ -62,7 +63,9 @@ entry: ret <4 x float> %v0 ; CHECK-LABEL: @test2 +; CHECK: fptrunc <4 x double> %d to <4 x float> ; CHECK-NOT: @llvm.ppc.qpx.qvstfs +; CHECK-NOT: store <4 x double> ; CHECK: ret <4 x float> } -- 2.34.1