[InstCombine/PowerPC] Fix single-precision QPX load/store replacement
authorHal Finkel <hfinkel@anl.gov>
Mon, 11 May 2015 06:37:03 +0000 (06:37 +0000)
committerHal Finkel <hfinkel@anl.gov>
Mon, 11 May 2015 06:37:03 +0000 (06:37 +0000)
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
test/Transforms/InstCombine/aligned-qpx.ll

index 20c5a897b967f4e5bde8e78c411aae00e5e984fc..cae611f21b210e7d1c9c85f1b24c6c6b4212cf2d 100644 (file)
@@ -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:
index e303ddd17d5c83c4cf88ae09941acbd6ae4d8258..e9710df5670cd0775d89e31cc13dab5a7e363299 100644 (file)
@@ -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>
 }