mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-30 16:17:05 +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