diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -15994,31 +15994,54 @@ } } -// Currently this is a copy from AArch64TargetLowering::isProfitableToHoist. // FIXME: add more patterns which are profitable to hoist. bool PPCTargetLowering::isProfitableToHoist(Instruction *I) const { - if (I->getOpcode() != Instruction::FMul) - return true; + switch (I->getOpcode()) { + case Instruction::FMul: { + // Don't break FMA, PowerPC prefers FMA. + if (!I->hasOneUse()) + return true; - if (!I->hasOneUse()) - return true; + Instruction *User = I->user_back(); + assert(User && "A single use instruction with no uses."); - Instruction *User = I->user_back(); - assert(User && "A single use instruction with no uses."); + if (User->getOpcode() != Instruction::FSub && + User->getOpcode() != Instruction::FAdd) + return true; - if (User->getOpcode() != Instruction::FSub && - User->getOpcode() != Instruction::FAdd) - return true; + const TargetOptions &Options = getTargetMachine().Options; + const Function *F = I->getFunction(); + const DataLayout &DL = F->getParent()->getDataLayout(); + Type *Ty = User->getOperand(0)->getType(); + + return !( + isFMAFasterThanFMulAndFAdd(*F, Ty) && + isOperationLegalOrCustom(ISD::FMA, getValueType(DL, Ty)) && + (Options.AllowFPOpFusion == FPOpFusion::Fast || Options.UnsafeFPMath)); + } + case Instruction::Load: { + // Don't break "store (load float*)" pattern, this pattern will be combined + // to "store (load int32)" in later InstCombine pass. See function + // combineLoadToOperationType. On PowerPC, loading a float point takes more + // cycles than loading a 32 bit integer. + if (!I->hasOneUse() || I->getType()->getTypeID() != Type::FloatTyID) + return true; + LoadInst *LI = cast(I); + if (!LI->isUnordered() || LI->getPointerOperand()->isSwiftError()) + return true; - const TargetOptions &Options = getTargetMachine().Options; - const Function *F = I->getFunction(); - const DataLayout &DL = F->getParent()->getDataLayout(); - Type *Ty = User->getOperand(0)->getType(); - - return !( - isFMAFasterThanFMulAndFAdd(*F, Ty) && - isOperationLegalOrCustom(ISD::FMA, getValueType(DL, Ty)) && - (Options.AllowFPOpFusion == FPOpFusion::Fast || Options.UnsafeFPMath)); + Instruction *User = I->user_back(); + assert(User && "A single use instruction with no uses."); + + if (User->getOpcode() != Instruction::Store) + return true; + + return false; + } + default: + return true; + } + return true; } const MCPhysReg * diff --git a/llvm/test/Transforms/SimplifyCFG/PowerPC/prefer-load-i32.ll b/llvm/test/Transforms/SimplifyCFG/PowerPC/prefer-load-i32.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/PowerPC/prefer-load-i32.ll @@ -0,0 +1,30 @@ +; RUN: opt < %s -mtriple=powerpc64le-unknown-linux-gnu -simplifycfg -S | \ +; RUN: FileCheck %s + +define float @foo(float* %src, float* %dest, i32 signext %count, i32 signext %cond) { +entry: + %cmp = icmp sgt i32 %cond, 10 + %idxprom = sext i32 %count to i64 + %arrayidx = getelementptr inbounds float, float* %src, i64 %idxprom + br i1 %cmp, label %if.then, label %if.else + +; CHECK-LABEL: if.then: +; CHECK: %0 = load float, float* %arrayidx, align 4 +if.then: ; preds = %entry + %0 = load float, float* %arrayidx, align 4 + br label %if.end + +; CHECK-LABEL: if.else: +; CHECK: %1 = load float, float* %arrayidx, align 4 +; CHECK: store float %1, float* %arrayidx4, align 4 +if.else: ; preds = %entry + %1 = load float, float* %arrayidx, align 4 + %idxprom3 = sext i32 %count to i64 + %arrayidx4 = getelementptr inbounds float, float* %dest, i64 %idxprom3 + store float %1, float* %arrayidx4, align 4 + br label %if.end + +if.end: ; preds = %if.else, %if.then + %res2.0 = phi float [ %0, %if.then ], [ 0.000000e+00, %if.else ] + ret float %res2.0 +}