mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	[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
This commit is contained in:
		| @@ -624,9 +624,12 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { | |||||||
|     // Turn PPC QPX qvlfs -> load if the pointer is known aligned. |     // Turn PPC QPX qvlfs -> load if the pointer is known aligned. | ||||||
|     if (getOrEnforceKnownAlignment(II->getArgOperand(0), 16, DL, II, AC, DT) >= |     if (getOrEnforceKnownAlignment(II->getArgOperand(0), 16, DL, II, AC, DT) >= | ||||||
|         16) { |         16) { | ||||||
|  |       Type *VTy = VectorType::get(Builder->getFloatTy(), | ||||||
|  |                                   II->getType()->getVectorNumElements()); | ||||||
|       Value *Ptr = Builder->CreateBitCast(II->getArgOperand(0), |       Value *Ptr = Builder->CreateBitCast(II->getArgOperand(0), | ||||||
|                                          PointerType::getUnqual(II->getType())); |                                          PointerType::getUnqual(VTy)); | ||||||
|       return new LoadInst(Ptr); |       Value *Load = Builder->CreateLoad(Ptr); | ||||||
|  |       return new FPExtInst(Load, II->getType()); | ||||||
|     } |     } | ||||||
|     break; |     break; | ||||||
|   case Intrinsic::ppc_qpx_qvlfd: |   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. |     // Turn PPC QPX qvstfs -> store if the pointer is known aligned. | ||||||
|     if (getOrEnforceKnownAlignment(II->getArgOperand(1), 16, DL, II, AC, DT) >= |     if (getOrEnforceKnownAlignment(II->getArgOperand(1), 16, DL, II, AC, DT) >= | ||||||
|         16) { |         16) { | ||||||
|       Type *OpPtrTy = |       Type *VTy = VectorType::get(Builder->getFloatTy(), | ||||||
|         PointerType::getUnqual(II->getArgOperand(0)->getType()); |           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); |       Value *Ptr = Builder->CreateBitCast(II->getArgOperand(1), OpPtrTy); | ||||||
|       return new StoreInst(II->getArgOperand(0), Ptr); |       return new StoreInst(TOp, Ptr); | ||||||
|     } |     } | ||||||
|     break; |     break; | ||||||
|   case Intrinsic::ppc_qpx_qvstfd: |   case Intrinsic::ppc_qpx_qvstfd: | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ entry: | |||||||
|  |  | ||||||
| ; CHECK-LABEL: @test1a | ; CHECK-LABEL: @test1a | ||||||
| ; CHECK-NOT: @llvm.ppc.qpx.qvlfs | ; CHECK-NOT: @llvm.ppc.qpx.qvlfs | ||||||
|  | ; CHECK-NOT: load <4 x double> | ||||||
| ; CHECK: ret <4 x double> | ; CHECK: ret <4 x double> | ||||||
|  |  | ||||||
|   %v0 = load <4 x float>, <4 x float>* %h, align 8 |   %v0 = load <4 x float>, <4 x float>* %h, align 8 | ||||||
| @@ -62,7 +63,9 @@ entry: | |||||||
|   ret <4 x float> %v0 |   ret <4 x float> %v0 | ||||||
|  |  | ||||||
| ; CHECK-LABEL: @test2 | ; CHECK-LABEL: @test2 | ||||||
|  | ; CHECK: fptrunc <4 x double> %d to <4 x float> | ||||||
| ; CHECK-NOT: @llvm.ppc.qpx.qvstfs | ; CHECK-NOT: @llvm.ppc.qpx.qvstfs | ||||||
|  | ; CHECK-NOT: store <4 x double> | ||||||
| ; CHECK: ret <4 x float> | ; CHECK: ret <4 x float> | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user