[cfe-commits] r144054 - in /cfe/trunk: include/clang/Basic/TargetBuiltins.h lib/CodeGen/CGBuiltin.cpp lib/Sema/SemaChecking.cpp utils/TableGen/NeonEmitter.cpp utils/TableGen/NeonEmitter.h

Bob Wilson bob.wilson at apple.com
Mon Nov 7 17:16:12 PST 2011


Author: bwilson
Date: Mon Nov  7 19:16:11 2011
New Revision: 144054

URL: http://llvm.org/viewvc/llvm-project?rev=144054&view=rev
Log:
Clean up type flags for overloaded Neon builtins.  No functional change.

This patch just adds a simple NeonTypeFlags class to replace the various
hardcoded constants that had been used until now.  Unfortunately I couldn't
figure out a good way to avoid duplicating that class between clang and
TableGen, but since it's small and rarely changes, that's not so bad.

Modified:
    cfe/trunk/include/clang/Basic/TargetBuiltins.h
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/utils/TableGen/NeonEmitter.cpp
    cfe/trunk/utils/TableGen/NeonEmitter.h

Modified: cfe/trunk/include/clang/Basic/TargetBuiltins.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetBuiltins.h?rev=144054&r1=144053&r2=144054&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TargetBuiltins.h (original)
+++ cfe/trunk/include/clang/Basic/TargetBuiltins.h Mon Nov  7 19:16:11 2011
@@ -56,6 +56,46 @@
     };
   }
 
+  /// NeonTypeFlags - Flags to identify the types for overloaded Neon
+  /// builtins.  These must be kept in sync with the flags in
+  /// utils/TableGen/NeonEmitter.h.
+  class NeonTypeFlags {
+    enum {
+      EltTypeMask = 0xf,
+      UnsignedFlag = 0x10,
+      QuadFlag = 0x20
+    };
+    uint32_t Flags;
+
+  public:
+    enum EltType {
+      Int8,
+      Int16,
+      Int32,
+      Int64,
+      Poly8,
+      Poly16,
+      Float16,
+      Float32
+    };
+
+    NeonTypeFlags(unsigned F) : Flags(F) {}
+    NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
+      if (IsUnsigned)
+        Flags |= UnsignedFlag;
+      if (IsQuad)
+        Flags |= QuadFlag;
+    }
+
+    EltType getEltType() const { return (EltType)(Flags & EltTypeMask); }
+    bool isPoly() const {
+      EltType ET = getEltType();
+      return ET == Poly8 || ET == Poly16;
+    }
+    bool isUnsigned() const { return (Flags & UnsignedFlag) != 0; }
+    bool isQuad() const { return (Flags & QuadFlag) != 0; }
+  };
+
 } // end namespace clang.
 
 #endif

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=144054&r1=144053&r2=144054&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Nov  7 19:16:11 2011
@@ -1186,17 +1186,23 @@
   }
 }
 
-static llvm::VectorType *GetNeonType(LLVMContext &C, unsigned type, bool q) {
-  switch (type) {
-    default: break;
-    case 0: 
-    case 5: return llvm::VectorType::get(llvm::Type::getInt8Ty(C), 8 << (int)q);
-    case 6:
-    case 7:
-    case 1: return llvm::VectorType::get(llvm::Type::getInt16Ty(C),4 << (int)q);
-    case 2: return llvm::VectorType::get(llvm::Type::getInt32Ty(C),2 << (int)q);
-    case 3: return llvm::VectorType::get(llvm::Type::getInt64Ty(C),1 << (int)q);
-    case 4: return llvm::VectorType::get(llvm::Type::getFloatTy(C),2 << (int)q);
+static llvm::VectorType *GetNeonType(LLVMContext &C, NeonTypeFlags Type) {
+  int IsQuad = Type.isQuad();
+  switch (Type.getEltType()) {
+  default: break;
+  case NeonTypeFlags::Int8:
+  case NeonTypeFlags::Poly8:
+    return llvm::VectorType::get(llvm::Type::getInt8Ty(C), 8 << IsQuad);
+  case NeonTypeFlags::Int16:
+  case NeonTypeFlags::Poly16:
+  case NeonTypeFlags::Float16:
+    return llvm::VectorType::get(llvm::Type::getInt16Ty(C), 4 << IsQuad);
+  case NeonTypeFlags::Int32:
+    return llvm::VectorType::get(llvm::Type::getInt32Ty(C), 2 << IsQuad);
+  case NeonTypeFlags::Int64:
+    return llvm::VectorType::get(llvm::Type::getInt64Ty(C), 1 << IsQuad);
+  case NeonTypeFlags::Float32:
+    return llvm::VectorType::get(llvm::Type::getFloatTy(C), 2 << IsQuad);
   };
   return 0;
 }
@@ -1363,14 +1369,12 @@
   }
   
   // Determine the type of this overloaded NEON intrinsic.
-  unsigned type = Result.getZExtValue();
-  bool usgn = type & 0x08;
-  bool quad = type & 0x10;
-  bool poly = (type & 0x7) == 5 || (type & 0x7) == 6;
-  (void)poly;  // Only used in assert()s.
+  NeonTypeFlags Type(Result.getZExtValue());
+  bool usgn = Type.isUnsigned();
+  bool quad = Type.isQuad();
   bool rightShift = false;
 
-  llvm::VectorType *VTy = GetNeonType(getLLVMContext(), type & 0x7, quad);
+  llvm::VectorType *VTy = GetNeonType(getLLVMContext(), Type);
   llvm::Type *Ty = VTy;
   if (!Ty)
     return 0;
@@ -1429,34 +1433,43 @@
     return EmitNeonCall(F, Ops, "vcnt");
   }
   case ARM::BI__builtin_neon_vcvt_f16_v: {
-    assert((type & 0x7) == 7 && !quad && "unexpected vcvt_f16_v builtin");
+    assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad &&
+           "unexpected vcvt_f16_v builtin");
     Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvtfp2hf);
     return EmitNeonCall(F, Ops, "vcvt");
   }
   case ARM::BI__builtin_neon_vcvt_f32_f16: {
-    assert((type & 0x7) == 7 && !quad && "unexpected vcvt_f32_f16 builtin");
+    assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad &&
+           "unexpected vcvt_f32_f16 builtin");
     Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvthf2fp);
     return EmitNeonCall(F, Ops, "vcvt");
   }
   case ARM::BI__builtin_neon_vcvt_f32_v:
-  case ARM::BI__builtin_neon_vcvtq_f32_v: {
+  case ARM::BI__builtin_neon_vcvtq_f32_v:
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ty = GetNeonType(getLLVMContext(), 4, quad);
+    Ty = GetNeonType(getLLVMContext(),
+                     NeonTypeFlags(NeonTypeFlags::Float32, false, quad));
     return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 
                 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
-  }
   case ARM::BI__builtin_neon_vcvt_s32_v:
   case ARM::BI__builtin_neon_vcvt_u32_v:
   case ARM::BI__builtin_neon_vcvtq_s32_v:
   case ARM::BI__builtin_neon_vcvtq_u32_v: {
-    Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(getLLVMContext(), 4, quad));
+    llvm::Type *FloatTy =
+      GetNeonType(getLLVMContext(),
+                  NeonTypeFlags(NeonTypeFlags::Float32, false, quad));
+    Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy);
     return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 
                 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt");
   }
   case ARM::BI__builtin_neon_vcvt_n_f32_v:
   case ARM::BI__builtin_neon_vcvtq_n_f32_v: {
-    llvm::Type *Tys[2] = { GetNeonType(getLLVMContext(), 4, quad), Ty };
-    Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp : Intrinsic::arm_neon_vcvtfxs2fp;
+    llvm::Type *FloatTy =
+      GetNeonType(getLLVMContext(),
+                  NeonTypeFlags(NeonTypeFlags::Float32, false, quad));
+    llvm::Type *Tys[2] = { FloatTy, Ty };
+    Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp
+               : Intrinsic::arm_neon_vcvtfxs2fp;
     Function *F = CGM.getIntrinsic(Int, Tys);
     return EmitNeonCall(F, Ops, "vcvt_n");
   }
@@ -1464,8 +1477,12 @@
   case ARM::BI__builtin_neon_vcvt_n_u32_v:
   case ARM::BI__builtin_neon_vcvtq_n_s32_v:
   case ARM::BI__builtin_neon_vcvtq_n_u32_v: {
-    llvm::Type *Tys[2] = { Ty, GetNeonType(getLLVMContext(), 4, quad) };
-    Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu : Intrinsic::arm_neon_vcvtfp2fxs;
+    llvm::Type *FloatTy =
+      GetNeonType(getLLVMContext(),
+                  NeonTypeFlags(NeonTypeFlags::Float32, false, quad));
+    llvm::Type *Tys[2] = { Ty, FloatTy };
+    Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu
+               : Intrinsic::arm_neon_vcvtfp2fxs;
     Function *F = CGM.getIntrinsic(Int, Tys);
     return EmitNeonCall(F, Ops, "vcvt_n");
   }
@@ -1656,12 +1673,12 @@
   }
   case ARM::BI__builtin_neon_vmul_v:
   case ARM::BI__builtin_neon_vmulq_v:
-    assert(poly && "vmul builtin only supported for polynomial types");
+    assert(Type.isPoly() && "vmul builtin only supported for polynomial types");
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmulp, Ty),
                         Ops, "vmul");
   case ARM::BI__builtin_neon_vmull_v:
     Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
-    Int = poly ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
+    Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
     return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
   case ARM::BI__builtin_neon_vpadal_v:
   case ARM::BI__builtin_neon_vpadalq_v: {

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=144054&r1=144053&r2=144054&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Nov  7 19:16:11 2011
@@ -245,27 +245,25 @@
 
 // Get the valid immediate range for the specified NEON type code.
 static unsigned RFT(unsigned t, bool shift = false) {
-  bool quad = t & 0x10;
-  
-  switch (t & 0x7) {
-    case 0: // i8
-      return shift ? 7 : (8 << (int)quad) - 1;
-    case 1: // i16
-      return shift ? 15 : (4 << (int)quad) - 1;
-    case 2: // i32
-      return shift ? 31 : (2 << (int)quad) - 1;
-    case 3: // i64
-      return shift ? 63 : (1 << (int)quad) - 1;
-    case 4: // f32
-      assert(!shift && "cannot shift float types!");
-      return (2 << (int)quad) - 1;
-    case 5: // poly8
-      return shift ? 7 : (8 << (int)quad) - 1;
-    case 6: // poly16
-      return shift ? 15 : (4 << (int)quad) - 1;
-    case 7: // float16
-      assert(!shift && "cannot shift float types!");
-      return (4 << (int)quad) - 1;
+  NeonTypeFlags Type(t);
+  int IsQuad = Type.isQuad();
+  switch (Type.getEltType()) {
+  case NeonTypeFlags::Int8:
+  case NeonTypeFlags::Poly8:
+    return shift ? 7 : (8 << IsQuad) - 1;
+  case NeonTypeFlags::Int16:
+  case NeonTypeFlags::Poly16:
+    return shift ? 15 : (4 << IsQuad) - 1;
+  case NeonTypeFlags::Int32:
+    return shift ? 31 : (2 << IsQuad) - 1;
+  case NeonTypeFlags::Int64:
+    return shift ? 63 : (1 << IsQuad) - 1;
+  case NeonTypeFlags::Float16:
+    assert(!shift && "cannot shift float types!");
+    return (4 << IsQuad) - 1;
+  case NeonTypeFlags::Float32:
+    assert(!shift && "cannot shift float types!");
+    return (2 << IsQuad) - 1;
   }
   return 0;
 }
@@ -288,8 +286,8 @@
     if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))
       return true;
     
-    TV = Result.getLimitedValue(32);
-    if ((TV > 31) || (mask & (1 << TV)) == 0)
+    TV = Result.getLimitedValue(64);
+    if ((TV > 63) || (mask & (1 << TV)) == 0)
       return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code)
         << TheCall->getArg(ArgNo)->getSourceRange();
   }

Modified: cfe/trunk/utils/TableGen/NeonEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/NeonEmitter.cpp?rev=144054&r1=144053&r2=144054&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/NeonEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/NeonEmitter.cpp Mon Nov  7 19:16:11 2011
@@ -833,7 +833,6 @@
 
 static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
   unsigned mod = proto[0];
-  unsigned ret = 0;
 
   if (mod == 'v' || mod == 'f')
     mod = proto[1];
@@ -851,35 +850,32 @@
   // Based on the modifying character, change the type and width if necessary.
   type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
 
-  if (usgn)
-    ret |= 0x08;
-  if (quad && proto[1] != 'g')
-    ret |= 0x10;
-
+  NeonTypeFlags::EltType ET;
   switch (type) {
     case 'c':
-      ret |= poly ? 5 : 0;
+      ET = poly ? NeonTypeFlags::Poly8 : NeonTypeFlags::Int8;
       break;
     case 's':
-      ret |= poly ? 6 : 1;
+      ET = poly ? NeonTypeFlags::Poly16 : NeonTypeFlags::Int16;
       break;
     case 'i':
-      ret |= 2;
+      ET = NeonTypeFlags::Int32;
       break;
     case 'l':
-      ret |= 3;
+      ET = NeonTypeFlags::Int64;
       break;
     case 'h':
-      ret |= 7;
+      ET = NeonTypeFlags::Float16;
       break;
     case 'f':
-      ret |= 4;
+      ET = NeonTypeFlags::Float32;
       break;
     default:
       throw "unhandled type!";
       break;
   }
-  return ret;
+  NeonTypeFlags Flags(ET, usgn, quad && proto[1] != 'g');
+  return Flags.getFlags();
 }
 
 // Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a)

Modified: cfe/trunk/utils/TableGen/NeonEmitter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/NeonEmitter.h?rev=144054&r1=144053&r2=144054&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/NeonEmitter.h (original)
+++ cfe/trunk/utils/TableGen/NeonEmitter.h Mon Nov  7 19:16:11 2011
@@ -86,6 +86,40 @@
   ClassB            // bitcast arguments with enum argument to specify type
 };
 
+/// NeonTypeFlags - Flags to identify the types for overloaded Neon
+/// builtins.  These must be kept in sync with the flags in
+/// include/clang/Basic/TargetBuiltins.h.
+class NeonTypeFlags {
+  enum {
+    EltTypeMask = 0xf,
+    UnsignedFlag = 0x10,
+    QuadFlag = 0x20
+  };
+  uint32_t Flags;
+
+public:
+  enum EltType {
+    Int8,
+    Int16,
+    Int32,
+    Int64,
+    Poly8,
+    Poly16,
+    Float16,
+    Float32
+  };
+
+  NeonTypeFlags(unsigned F) : Flags(F) {}
+  NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
+    if (IsUnsigned)
+      Flags |= UnsignedFlag;
+    if (IsQuad)
+      Flags |= QuadFlag;
+  }
+
+  uint32_t getFlags() const { return Flags; }
+};
+
 namespace llvm {
 
   class NeonEmitter : public TableGenBackend {





More information about the cfe-commits mailing list