[PPC] Prefer direct move on power8 if load 1 or 2 bytes to VSR

Power8 has MTVSRWZ but no LXSIBZX/LXSIHZX, so move 1 or 2 bytes to VSR through MTVSRWZ is much faster than store the extended value into stack and load it with LXSIWZX.
This patch fixes pr31144.

Differential Revision: https://reviews.llvm.org/D27287

llvm-svn: 289473
This commit is contained in:
Guozhi Wei 2016-12-12 22:09:02 +00:00
parent 1af286f06d
commit d15522bb98
3 changed files with 35 additions and 1 deletions

View File

@ -6606,11 +6606,17 @@ void PPCTargetLowering::spliceIntoChain(SDValue ResChain,
/// \brief Analyze profitability of direct move
/// prefer float load to int load plus direct move
/// when there is no integer use of int load
static bool directMoveIsProfitable(const SDValue &Op) {
bool PPCTargetLowering::directMoveIsProfitable(const SDValue &Op) const {
SDNode *Origin = Op.getOperand(0).getNode();
if (Origin->getOpcode() != ISD::LOAD)
return true;
// If there is no LXSIBZX/LXSIHZX, like Power8,
// prefer direct move if the memory size is 1 or 2 bytes.
MachineMemOperand *MMO = cast<LoadSDNode>(Origin)->getMemOperand();
if (!Subtarget.hasP9Vector() && MMO->getSize() <= 2)
return true;
for (SDNode::use_iterator UI = Origin->use_begin(),
UE = Origin->use_end();
UI != UE; ++UI) {

View File

@ -815,6 +815,8 @@ namespace llvm {
SelectionDAG &DAG, const SDLoc &dl) const;
SDValue LowerFP_TO_INTDirectMove(SDValue Op, SelectionDAG &DAG,
const SDLoc &dl) const;
bool directMoveIsProfitable(const SDValue &Op) const;
SDValue LowerINT_TO_FPDirectMove(SDValue Op, SelectionDAG &DAG,
const SDLoc &dl) const;

View File

@ -0,0 +1,26 @@
; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mattr=+vsx < %s | FileCheck %s --implicit-check-not lxsiwzx
declare void @bar(double)
define void @foo1(i8* %p) {
entry:
%0 = load i8, i8* %p, align 1
%conv = uitofp i8 %0 to double
call void @bar(double %conv)
ret void
; CHECK-LABEL: @foo1
; CHECK: mtvsrwz
}
define void @foo2(i16* %p) {
entry:
%0 = load i16, i16* %p, align 2
%conv = uitofp i16 %0 to double
call void @bar(double %conv)
ret void
; CHECK-LABEL: @foo2
; CHECK: mtvsrwz
}