forked from OSchip/llvm-project
[PowerPC] add store (load float*) pattern to isProfitableToHoist
store (load float*) can be optimized to store(load i32*) in InstCombine pass. Add store (load float*) to isProfitableToHoist to make sure we don't break the opt in InstCombine pass. Reviewed By: jsji Differential Revision: https://reviews.llvm.org/D82341
This commit is contained in:
parent
cf55866185
commit
e8425b27fe
|
@ -16381,31 +16381,56 @@ bool PPCTargetLowering::isFMAFasterThanFMulAndFAdd(const Function &F,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently this is a copy from AArch64TargetLowering::isProfitableToHoist.
|
// FIXME: add more patterns which are not profitable to hoist.
|
||||||
// FIXME: add more patterns which are profitable to hoist.
|
|
||||||
bool PPCTargetLowering::isProfitableToHoist(Instruction *I) const {
|
bool PPCTargetLowering::isProfitableToHoist(Instruction *I) const {
|
||||||
if (I->getOpcode() != Instruction::FMul)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!I->hasOneUse())
|
if (!I->hasOneUse())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Instruction *User = I->user_back();
|
Instruction *User = I->user_back();
|
||||||
assert(User && "A single use instruction with no uses.");
|
assert(User && "A single use instruction with no uses.");
|
||||||
|
|
||||||
if (User->getOpcode() != Instruction::FSub &&
|
switch (I->getOpcode()) {
|
||||||
User->getOpcode() != Instruction::FAdd)
|
case Instruction::FMul: {
|
||||||
|
// Don't break FMA, PowerPC prefers FMA.
|
||||||
|
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.
|
||||||
|
LoadInst *LI = cast<LoadInst>(I);
|
||||||
|
// For the loads that combineLoadToOperationType does nothing, like
|
||||||
|
// ordered load, it should be profitable to hoist them.
|
||||||
|
// For swifterror load, it can only be used for pointer to pointer type, so
|
||||||
|
// later type check should get rid of this case.
|
||||||
|
if (!LI->isUnordered())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (User->getOpcode() != Instruction::Store)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (I->getType()->getTypeID() != Type::FloatTyID)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
default:
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
const TargetOptions &Options = getTargetMachine().Options;
|
return true;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCPhysReg *
|
const MCPhysReg *
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
define float @foo(float* %src, float* %dest, i32 signext %count, i32 signext %cond) {
|
define float @foo(float* %src, float* %dest, i32 signext %count, i32 signext %cond) {
|
||||||
; CHECK-LABEL: @foo(
|
; CHECK-LABEL: @foo(
|
||||||
; CHECK-LABEL: entry:
|
; CHECK-LABEL: entry:
|
||||||
; CHECK: %0 = load float, float* %arrayidx, align 4
|
; CHECK-NOT: load float
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp sgt i32 %cond, 10
|
%cmp = icmp sgt i32 %cond, 10
|
||||||
%idxprom = sext i32 %count to i64
|
%idxprom = sext i32 %count to i64
|
||||||
|
@ -11,14 +11,15 @@ entry:
|
||||||
br i1 %cmp, label %if.then, label %if.else
|
br i1 %cmp, label %if.then, label %if.else
|
||||||
|
|
||||||
; CHECK-LABEL: if.then:
|
; CHECK-LABEL: if.then:
|
||||||
; CHECK-NOT: load float
|
; CHECK: %0 = load float, float* %arrayidx, align 4
|
||||||
if.then: ; preds = %entry
|
if.then: ; preds = %entry
|
||||||
%0 = load float, float* %arrayidx, align 4
|
%0 = load float, float* %arrayidx, align 4
|
||||||
%res = fmul float %0, 3.000000e+00
|
%res = fmul float %0, 3.000000e+00
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
|
||||||
; CHECK-LABEL: if.else:
|
; CHECK-LABEL: if.else:
|
||||||
; CHECK-NOT: load float
|
; CHECK: %1 = load float, float* %arrayidx, align 4
|
||||||
|
; CHECK: store float %1, float* %arrayidx4, align 4
|
||||||
if.else: ; preds = %entry
|
if.else: ; preds = %entry
|
||||||
%1 = load float, float* %arrayidx, align 4
|
%1 = load float, float* %arrayidx, align 4
|
||||||
%idxprom3 = sext i32 %count to i64
|
%idxprom3 = sext i32 %count to i64
|
||||||
|
|
Loading…
Reference in New Issue