Skip to content

Commit 219acef

Browse files
committed
Update costs for AArch64
add/sub/cmp/cmn have different encoding requirements, which getImmCost, the variant that ONLY takes the uint64_t value, does not consider.
1 parent eb6577d commit 219acef

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,20 @@ AArch64TTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
413413
return std::max<InstructionCost>(1, Cost);
414414
}
415415

416+
static bool isLegalArithImmed(uint64_t C) {
417+
// Matches AArch64DAGToDAGISel::SelectArithImmed().
418+
bool IsLegal = (C >> 12 == 0) || ((C & 0xFFFULL) == 0 && C >> 24 == 0);
419+
LLVM_DEBUG(dbgs() << "Is imm " << C
420+
<< " legal: " << (IsLegal ? "yes\n" : "no\n"));
421+
return IsLegal;
422+
}
423+
424+
static bool isLegalCmpImmed(APInt C) {
425+
// Works for negative immediates too, as it can be written as an ADDS
426+
// instruction with a negated immediate.
427+
return isLegalArithImmed(C.abs().getZExtValue());
428+
}
429+
416430
InstructionCost AArch64TTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
417431
const APInt &Imm, Type *Ty,
418432
TTI::TargetCostKind CostKind,
@@ -473,10 +487,19 @@ InstructionCost AArch64TTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
473487

474488
if (Idx == ImmIdx) {
475489
int NumConstants = (BitSize + 63) / 64;
476-
InstructionCost Cost = AArch64TTIImpl::getIntImmCost(Imm, Ty, CostKind);
477-
return (Cost <= NumConstants * TTI::TCC_Basic)
478-
? static_cast<int>(TTI::TCC_Free)
479-
: Cost;
490+
InstructionCost Cost;
491+
if ((Opcode == Instruction::Add || Opcode == Instruction::Sub ||
492+
Opcode == Instruction::ICmp) &&
493+
BitSize <= 64) {
494+
// Add/Sub/ICmp immediates can be flipped.
495+
// Also they have different requirements as to fitting in an immediate
496+
// than others.
497+
if (isLegalCmpImmed(Imm))
498+
return TTI::TCC_Free;
499+
Cost = AArch64TTIImpl::getIntImmCost(Imm.abs(), Ty, CostKind);
500+
} else
501+
Cost = AArch64TTIImpl::getIntImmCost(Imm, Ty, CostKind);
502+
return (Cost <= NumConstants * TTI::TCC_Basic) ? TTI::TCC_Free : Cost;
480503
}
481504
return AArch64TTIImpl::getIntImmCost(Imm, Ty, CostKind);
482505
}
@@ -511,9 +534,7 @@ AArch64TTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
511534
if (Idx == 1) {
512535
int NumConstants = (BitSize + 63) / 64;
513536
InstructionCost Cost = AArch64TTIImpl::getIntImmCost(Imm, Ty, CostKind);
514-
return (Cost <= NumConstants * TTI::TCC_Basic)
515-
? static_cast<int>(TTI::TCC_Free)
516-
: Cost;
537+
return (Cost <= NumConstants * TTI::TCC_Basic) ? TTI::TCC_Free : Cost;
517538
}
518539
break;
519540
case Intrinsic::experimental_stackmap:

0 commit comments

Comments
 (0)