diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-12-02 21:49:08 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-06-04 11:59:04 +0000 |
| commit | 574b7079b96703a748f89ef5adb7dc3e26b8f7fc (patch) | |
| tree | 195000196b1e0cc13dea43258fa240e006f48184 /contrib/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp | |
| parent | 1f6fd64fe9c996b4795ee4a6c66b8f9216747560 (diff) | |
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(); |
