///
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "arm64tti"
#include "ARM64.h"
#include "ARM64TargetMachine.h"
#include "MCTargetDesc/ARM64AddressingModes.h"
#include <algorithm>
using namespace llvm;
+#define DEBUG_TYPE "arm64tti"
+
// Declare the pass initialization routine locally as target-specific passes
// don't havve a target-wide initialization entry point, and so we rely on the
// pass constructor initialization.
unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const;
public:
- ARM64TTI() : ImmutablePass(ID), TM(0), ST(0), TLI(0) {
+ ARM64TTI() : ImmutablePass(ID), TM(nullptr), ST(nullptr), TLI(nullptr) {
llvm_unreachable("This pass cannot be directly constructed");
}
/// @{
unsigned getNumberOfRegisters(bool Vector) const override {
- if (Vector)
- return 32;
-
+ if (Vector) {
+ if (ST->hasNEON())
+ return 32;
+ return 0;
+ }
return 31;
}
unsigned getRegisterBitWidth(bool Vector) const override {
- if (Vector)
- return 128;
-
+ if (Vector) {
+ if (ST->hasNEON())
+ return 128;
+ return 0;
+ }
return 64;
}
assert(Ty->isIntegerTy());
unsigned BitSize = Ty->getPrimitiveSizeInBits();
- if (BitSize == 0 || BitSize > 128)
+ if (BitSize == 0)
return ~0U;
// Sign-extend all constants to a multiple of 64-bit.
// chunk.
unsigned Cost = 0;
for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) {
- APInt Tmp = ImmVal.ashr(ShiftVal).getLoBits(64);
+ APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64);
int64_t Val = Tmp.getSExtValue();
Cost += getIntImmCost(Val);
}
assert(Ty->isIntegerTy());
unsigned BitSize = Ty->getPrimitiveSizeInBits();
- if (BitSize == 0 || BitSize > 128)
- return ~0U;
+ // There is no cost model for constants with a bit size of 0. Return TCC_Free
+ // here, so that constant hoisting will ignore this constant.
+ if (BitSize == 0)
+ return TCC_Free;
unsigned ImmIdx = ~0U;
switch (Opcode) {
case Instruction::SDiv:
case Instruction::URem:
case Instruction::SRem:
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
case Instruction::ICmp:
ImmIdx = 1;
break;
+ // Always return TCC_Free for the shift value of a shift instruction.
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ if (Idx == 1)
+ return TCC_Free;
+ break;
case Instruction::Trunc:
case Instruction::ZExt:
case Instruction::SExt:
if (Idx == ImmIdx) {
unsigned NumConstants = (BitSize + 63) / 64;
unsigned Cost = ARM64TTI::getIntImmCost(Imm, Ty);
- return (Cost <= NumConstants * TCC_Basic) ? TCC_Free : Cost;
+ return (Cost <= NumConstants * TCC_Basic)
+ ? static_cast<unsigned>(TCC_Free) : Cost;
}
return ARM64TTI::getIntImmCost(Imm, Ty);
}
assert(Ty->isIntegerTy());
unsigned BitSize = Ty->getPrimitiveSizeInBits();
- if (BitSize == 0 || BitSize > 128)
- return ~0U;
+ // There is no cost model for constants with a bit size of 0. Return TCC_Free
+ // here, so that constant hoisting will ignore this constant.
+ if (BitSize == 0)
+ return TCC_Free;
switch (IID) {
default:
if (Idx == 1) {
unsigned NumConstants = (BitSize + 63) / 64;
unsigned Cost = ARM64TTI::getIntImmCost(Imm, Ty);
- return (Cost <= NumConstants * TCC_Basic) ? TCC_Free : Cost;
+ return (Cost <= NumConstants * TCC_Basic)
+ ? static_cast<unsigned>(TCC_Free) : Cost;
}
break;
case Intrinsic::experimental_stackmap:
{ ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, 1 },
{ ISD::FP_TO_UINT, MVT::v2i32, MVT::v2f64, 1 },
{ ISD::FP_TO_SINT, MVT::v2i32, MVT::v2f64, 1 },
+ { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f32, 4 },
+ { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f32, 4 },
+ { ISD::FP_TO_UINT, MVT::v4i16, MVT::v4f32, 4 },
+ { ISD::FP_TO_SINT, MVT::v4i16, MVT::v4f32, 4 },
{ ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, 4 },
{ ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f64, 4 },
};