@@ -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+
416430InstructionCost 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