Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h @@ -815,6 +815,8 @@ 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; Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp @@ -6606,11 +6606,17 @@ /// \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(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) { Index: llvm/trunk/test/CodeGen/PowerPC/pr31144.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/pr31144.ll +++ llvm/trunk/test/CodeGen/PowerPC/pr31144.ll @@ -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 +} +