diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp b/contrib/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp index 88de84a4fd78..602c6745d310 100644 --- a/contrib/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp +++ b/contrib/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp @@ -334,8 +334,9 @@ InstructionCost ARMTTIImpl::getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx, } // Checks whether Inst is part of a min(max()) or max(min()) pattern -// that will match to an SSAT instruction -static bool isSSATMinMaxPattern(Instruction *Inst, const APInt &Imm) { +// that will match to an SSAT instruction. Returns the instruction being +// saturated, or null if no saturation pattern was found. +static Value *isSSATMinMaxPattern(Instruction *Inst, const APInt &Imm) { Value *LHS, *RHS; ConstantInt *C; SelectPatternFlavor InstSPF = matchSelectPattern(Inst, LHS, RHS).Flavor; @@ -358,12 +359,27 @@ static bool isSSATMinMaxPattern(Instruction *Inst, const APInt &Imm) { return false; }; - if (isSSatMin(Inst->getOperand(1)) || - (Inst->hasNUses(2) && (isSSatMin(*Inst->user_begin()) || - isSSatMin(*(++Inst->user_begin()))))) - return true; + if (isSSatMin(Inst->getOperand(1))) + return cast<Instruction>(Inst->getOperand(1))->getOperand(1); + if (Inst->hasNUses(2) && + (isSSatMin(*Inst->user_begin()) || isSSatMin(*(++Inst->user_begin())))) + return Inst->getOperand(1); } - return false; + return nullptr; +} + +// Look for a FP Saturation pattern, where the instruction can be simplified to +// a fptosi.sat. max(min(fptosi)). The constant in this case is always free. +static bool isFPSatMinMaxPattern(Instruction *Inst, const APInt &Imm) { + if (Imm.getBitWidth() != 64 || + Imm != APInt::getHighBitsSet(64, 33)) // -2147483648 + return false; + Value *FP = isSSATMinMaxPattern(Inst, Imm); + if (!FP && isa<ICmpInst>(Inst) && Inst->hasOneUse()) + FP = isSSATMinMaxPattern(cast<Instruction>(*Inst->user_begin()), Imm); + if (!FP) + return false; + return isa<FPToSIInst>(FP); } InstructionCost ARMTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx, @@ -423,6 +439,9 @@ InstructionCost ARMTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx, return 0; } + if (Inst && ST->hasVFP2Base() && isFPSatMinMaxPattern(Inst, Imm)) + return 0; + // We can convert <= -1 to < 0, which is generally quite cheap. if (Inst && Opcode == Instruction::ICmp && Idx == 1 && Imm.isAllOnesValue()) { ICmpInst::Predicate Pred = cast<ICmpInst>(Inst)->getPredicate(); |
