]> granicus.if.org Git - clang/commitdiff
[PPC] Move argument range checks for HTM and crypto builtins to Sema
authorKit Barton <kbarton@ca.ibm.com>
Mon, 30 Mar 2015 19:40:59 +0000 (19:40 +0000)
committerKit Barton <kbarton@ca.ibm.com>
Mon, 30 Mar 2015 19:40:59 +0000 (19:40 +0000)
The argument range checks for the HTM and Crypto builtins were implemented in
CGBuiltin.cpp, not in Sema. This change moves them to the appropriate location
in SemaChecking.cpp. It requires the creation of a new method in the Sema class
to do checks for PPC-specific builtins.

http://reviews.llvm.org/D8672

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@233586 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/CodeGen/CGBuiltin.cpp
lib/Sema/SemaChecking.cpp
test/CodeGen/builtins-ppc-crypto-diag.c [deleted file]
test/Sema/builtins-ppc.c [new file with mode: 0644]

index 7078cd8cdca8b68d1bfd241410ab68b538df4c98..ddd693a1c96368e7dbf9c23e7cb40db8b5961ce9 100644 (file)
@@ -8459,7 +8459,8 @@ private:
   bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
-
+  bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  
   bool SemaBuiltinVAStart(CallExpr *TheCall);
   bool SemaBuiltinVAStartARM(CallExpr *Call);
   bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
index 35597fe4a0b7632f4dcebd2abfd5b6d20fb73e0f..90ca218a837559f7391e0442b6a36a8048adb01c 100644 (file)
@@ -6371,119 +6371,6 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
     llvm::Function *F = CGM.getIntrinsic(ID);
     return Builder.CreateCall(F, Ops, "");
   }
-
-  // P8 Crypto builtins
-  case PPC::BI__builtin_altivec_crypto_vshasigmaw:
-  case PPC::BI__builtin_altivec_crypto_vshasigmad:
-  {
-    ConstantInt *CI1 = dyn_cast<ConstantInt>(Ops[1]);
-    ConstantInt *CI2 = dyn_cast<ConstantInt>(Ops[2]);
-    assert(CI1 && CI2);
-    if (CI1->getZExtValue() > 1) {
-      CGM.Error(E->getArg(1)->getExprLoc(),
-                "argument out of range (should be 0-1).");
-      return llvm::UndefValue::get(Ops[0]->getType());
-    }
-    if (CI2->getZExtValue() > 15) {
-      CGM.Error(E->getArg(2)->getExprLoc(),
-                "argument out of range (should be 0-15).");
-      return llvm::UndefValue::get(Ops[0]->getType());
-    }
-    switch (BuiltinID) {
-    default: llvm_unreachable("Unsupported sigma intrinsic!");
-    case PPC::BI__builtin_altivec_crypto_vshasigmaw:
-      ID = Intrinsic::ppc_altivec_crypto_vshasigmaw;
-      break;
-    case PPC::BI__builtin_altivec_crypto_vshasigmad:
-      ID = Intrinsic::ppc_altivec_crypto_vshasigmad;
-      break;
-    }
-    llvm::Function *F = CGM.getIntrinsic(ID);
-    return Builder.CreateCall(F, Ops, "");
-  }
-
-  // HTM builtins
-  case PPC::BI__builtin_tbegin:
-  case PPC::BI__builtin_tend:
-  case PPC::BI__builtin_tsr: {
-    unsigned int MaxValue;
-    // The HTM instructions only accept one argument and with limited range.
-    ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]);
-    assert(CI);
-    switch (BuiltinID) {
-    case PPC::BI__builtin_tbegin:
-      ID = Intrinsic::ppc_tbegin;
-      MaxValue = 1;
-      break;
-    case PPC::BI__builtin_tend:
-      ID = Intrinsic::ppc_tend;
-      MaxValue = 1;
-      break;
-    case PPC::BI__builtin_tsr:
-      ID = Intrinsic::ppc_tsr;
-      MaxValue = 7;
-      break;
-    }
-    if (CI->getZExtValue() > MaxValue) {
-      std::stringstream ss;
-      ss << "argument out of range (should be 0 or " << MaxValue << ")";
-      CGM.Error(E->getArg(0)->getExprLoc(), ss.str());
-      return llvm::UndefValue::get(Ops[0]->getType());
-    }
-
-    llvm::Function *F = CGM.getIntrinsic(ID);
-    return Builder.CreateCall(F, Ops, "");
-  }
-  case PPC::BI__builtin_tabortdc:
-  case PPC::BI__builtin_tabortwc: {
-    // For wd and dc variant of tabort first argument must be a 5-bit constant
-    // integer
-    ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]);
-    assert(CI);
-    if (CI->getZExtValue() > 31) {
-      CGM.ErrorUnsupported(E->getArg(0), "argument out of range (should be 0-31)");
-      return llvm::UndefValue::get(Ops[0]->getType());
-    }
-    switch (BuiltinID) {
-    case PPC::BI__builtin_tabortdc:
-      ID = Intrinsic::ppc_tabortdc;
-      break;
-    case PPC::BI__builtin_tabortwc:
-      ID = Intrinsic::ppc_tabortwc;
-      break;
-    }
-    llvm::Function *F = CGM.getIntrinsic(ID);
-    return Builder.CreateCall(F, Ops, "");
-  }
-  case PPC::BI__builtin_tabortdci:
-  case PPC::BI__builtin_tabortwci: {
-    // For wd and dc variant of tabort first and third argument must be a
-    // 5-bit constant integer
-    ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]);
-    assert(CI);
-    if (CI->getZExtValue() > 31) {
-      CGM.ErrorUnsupported(E->getArg(0), "argument out of range (should be 0-31)");
-      return llvm::UndefValue::get(Ops[0]->getType());
-    }
-    CI = dyn_cast<ConstantInt>(Ops[2]);
-    assert(CI);
-    if (CI->getZExtValue() > 31) {
-      CGM.ErrorUnsupported(E->getArg(2), "argument out of range (should be 0-31)");
-      return llvm::UndefValue::get(Ops[2]->getType());
-    }
-    switch (BuiltinID) {
-    default: llvm_unreachable("Unsupported htm intrinsic!");
-    case PPC::BI__builtin_tabortdci:
-      ID = Intrinsic::ppc_tabortdci;
-      break;
-    case PPC::BI__builtin_tabortwci:
-      ID = Intrinsic::ppc_tabortwci;
-      break;
-    }
-    llvm::Function *F = CGM.getIntrinsic(ID);
-    return Builder.CreateCall(F, Ops, "");
-  }
-
   }
 }
 
index abcccbaf18f8870c0220dd74d9d8f9219c486c2b..3e3d60e053119747a1e5f6824d4ba99b3e977a54 100644 (file)
@@ -551,6 +551,12 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
         if (CheckX86BuiltinFunctionCall(BuiltinID, TheCall))
           return ExprError();
         break;
+      case llvm::Triple::ppc:
+      case llvm::Triple::ppc64:
+      case llvm::Triple::ppc64le:
+        if (CheckPPCBuiltinFunctionCall(BuiltinID, TheCall))
+          return ExprError();
+        break;
       default:
         break;
     }
@@ -895,6 +901,27 @@ bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   return SemaBuiltinConstantArgRange(TheCall, i, l, u);
 }
 
+bool Sema::CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  unsigned i = 0, l = 0, u = 0;
+  switch (BuiltinID) {
+  default: return false;
+  case PPC::BI__builtin_altivec_crypto_vshasigmaw:
+  case PPC::BI__builtin_altivec_crypto_vshasigmad:
+    return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) ||
+           SemaBuiltinConstantArgRange(TheCall, 2, 0, 15);
+  case PPC::BI__builtin_tbegin:
+  case PPC::BI__builtin_tend: i = 0; l = 0; u = 1; break;
+  case PPC::BI__builtin_tsr: i = 0; l = 0; u = 7; break;
+  case PPC::BI__builtin_tabortwc:
+  case PPC::BI__builtin_tabortdc: i = 0; l = 0; u = 31; break;
+  case PPC::BI__builtin_tabortwci:
+  case PPC::BI__builtin_tabortdci:
+    return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31) ||
+           SemaBuiltinConstantArgRange(TheCall, 2, 0, 31);
+  }
+  return SemaBuiltinConstantArgRange(TheCall, i, l, u);
+}
+
 bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   unsigned i = 0, l = 0, u = 0;
   switch (BuiltinID) {
diff --git a/test/CodeGen/builtins-ppc-crypto-diag.c b/test/CodeGen/builtins-ppc-crypto-diag.c
deleted file mode 100644 (file)
index 4408ab4..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// REQUIRES: powerpc-registered-target
-// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T1LW -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T1
-// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T1MW -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T1
-// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T2LW -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T2
-// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T2MW -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T2
-// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T1LD -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T1
-// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T1MD -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T1
-// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T2LD -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T2
-// RUN: not %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -D_T2MD -target-feature +crypto -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-T2
-#include <altivec.h>
-
-#define W_INIT { 0x01020304, 0x05060708, \
-                  0x090A0B0C, 0x0D0E0F10 };
-#define D_INIT { 0x0102030405060708, \
-                  0x090A0B0C0D0E0F10 };
-vector unsigned int test_vshasigmaw_or(void)
-{
-  vector unsigned int a = W_INIT
-#ifdef _T1LW // Arg1 too large
-  vector unsigned int b = __builtin_crypto_vshasigmaw(a, 2, 15);
-#elif defined(_T1MW) // Arg1 negative
-  vector unsigned int c = __builtin_crypto_vshasigmaw(a, -1, 15);
-#elif defined(_T2LW) // Arg2 too large
-  vector unsigned int d = __builtin_crypto_vshasigmaw(a, 0, 85);
-#elif defined(_T2MW) // Arg1 negative
-  vector unsigned int e = __builtin_crypto_vshasigmaw(a, 1, -15);
-#endif
-  return __builtin_crypto_vshasigmaw(a, 1, 15);
-}
-
-vector unsigned long long test_vshasigmad_or(void)
-{
-  vector unsigned long long a = D_INIT
-#ifdef _T1LD // Arg1 too large
-  vector unsigned long long b = __builtin_crypto_vshasigmad(a, 2, 15);
-#elif defined(_T1MD) // Arg1 negative
-  vector unsigned long long c = __builtin_crypto_vshasigmad(a, -1, 15);
-#elif defined(_T2LD) // Arg2 too large
-  vector unsigned long long d = __builtin_crypto_vshasigmad(a, 0, 85);
-#elif defined(_T2MD) // Arg1 negative
-  vector unsigned long long e = __builtin_crypto_vshasigmad(a, 1, -15);
-#endif
-  return __builtin_crypto_vshasigmad(a, 0, 15);
-}
-
-// CHECK-T1: error: argument out of range (should be 0-1).
-// CHECK-T2: error: argument out of range (should be 0-15).
diff --git a/test/Sema/builtins-ppc.c b/test/Sema/builtins-ppc.c
new file mode 100644 (file)
index 0000000..60872a6
--- /dev/null
@@ -0,0 +1,51 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -faltivec -target-feature +htm                       \
+// RUN: -triple powerpc64-unknown-unknown -DTEST_HTM -fsyntax-only      \
+// RUN: -verify %s
+
+// RUN: %clang_cc1 -faltivec -target-feature +crypto                    \
+// RUN: -triple powerpc64le-unknown-unknown -DTEST_CRYPTO -fsyntax-only      \
+// RUN: -verify %s
+
+#ifdef TEST_HTM
+void test_htm() {
+  __builtin_tbegin(4); // expected-error {{argument should be a value from 0 to 1}}
+  __builtin_tend(-1);  // expected-error {{argument should be a value from 0 to 1}}
+  __builtin_tsr(55);   // expected-error {{argument should be a value from 0 to 7}}
+  __builtin_tabortwc(-5, 2, 3); // expected-error {{argument should be a value from 0 to 31}} 
+  __builtin_tabortdc(55, 2, 3); // expected-error {{argument should be a value from 0 to 31}}
+  __builtin_tabortwci(-5, 2, 5); // expected-error {{argument should be a value from 0 to 31}}
+  __builtin_tabortwci(5, 2, 55); // expected-error {{argument should be a value from 0 to 31}}  
+  __builtin_tabortdci(-5, 2, 5); // expected-error {{argument should be a value from 0 to 31}}
+  __builtin_tabortdci(5, 2, 55); // expected-error {{argument should be a value from 0 to 31}}
+}
+#endif
+
+
+#ifdef TEST_CRYPTO
+#include <altivec.h>
+
+#define W_INIT { 0x01020304, 0x05060708, 0x090A0B0C, 0x0D0E0F10 };
+#define D_INIT { 0x0102030405060708, 0x090A0B0C0D0E0F10 };
+vector unsigned int test_vshasigmaw_or(void)
+{
+  vector unsigned int a = W_INIT
+  vector unsigned int b = __builtin_crypto_vshasigmaw(a, 2, 15);  // expected-error {{argument should be a value from 0 to 1}}
+  vector unsigned int c = __builtin_crypto_vshasigmaw(a, -1, 15); // expected-error {{argument should be a value from 0 to 1}}
+  vector unsigned int d = __builtin_crypto_vshasigmaw(a, 0, 85);  // expected-error {{argument should be a value from 0 to 15}}
+  vector unsigned int e = __builtin_crypto_vshasigmaw(a, 1, -15); // expected-error {{argument should be a value from 0 to 15}}
+  return __builtin_crypto_vshasigmaw(a, 1, 15);
+}
+
+vector unsigned long long test_vshasigmad_or(void)
+{
+  vector unsigned long long a = D_INIT
+  vector unsigned long long b = __builtin_crypto_vshasigmad(a, 2, 15);  // expected-error {{argument should be a value from 0 to 1}}
+  vector unsigned long long c = __builtin_crypto_vshasigmad(a, -1, 15); // expected-error {{argument should be a value from 0 to 1}}
+  vector unsigned long long d = __builtin_crypto_vshasigmad(a, 0, 85);  // expected-error {{argument should be a value from 0 to 1}}
+  vector unsigned long long e = __builtin_crypto_vshasigmad(a, 1, -15); // expected-error {{argument should be a value from 0 to 1}}
+  return __builtin_crypto_vshasigmad(a, 0, 15);
+}
+
+#endif
+