ARM64: diagnose use of v16-v31 in certain indexed NEON instructions.
[oota-llvm.git] / lib / Target / ARM64 / ARM64TargetTransformInfo.cpp
index cc8cc806ec7045dda11c46328aeddd1092d28001..ac7142f3febddb47efe238d868becdc4d2f8c7e7 100644 (file)
@@ -14,7 +14,6 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "arm64tti"
 #include "ARM64.h"
 #include "ARM64TargetMachine.h"
 #include "MCTargetDesc/ARM64AddressingModes.h"
@@ -25,6 +24,8 @@
 #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.
@@ -44,7 +45,7 @@ class ARM64TTI final : public ImmutablePass, public TargetTransformInfo {
   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");
   }
 
@@ -86,16 +87,20 @@ public:
   /// @{
 
   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;
   }
 
@@ -203,15 +208,19 @@ unsigned ARM64TTI::getIntImmCost(unsigned Opcode, unsigned Idx,
   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:
@@ -312,6 +321,10 @@ unsigned ARM64TTI::getCastInstrCost(unsigned Opcode, Type *Dst,
     { 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 },
   };