From e434e379e8ac99225ac090dd09ae243a9c212905 Mon Sep 17 00:00:00 2001 From: Kit Barton Date: Mon, 30 Mar 2015 19:40:59 +0000 Subject: [PATCH] [PPC] Move argument range checks for HTM and crypto builtins to Sema 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 | 3 +- lib/CodeGen/CGBuiltin.cpp | 113 ------------------------ lib/Sema/SemaChecking.cpp | 27 ++++++ test/CodeGen/builtins-ppc-crypto-diag.c | 47 ---------- test/Sema/builtins-ppc.c | 51 +++++++++++ 5 files changed, 80 insertions(+), 161 deletions(-) delete mode 100644 test/CodeGen/builtins-ppc-crypto-diag.c create mode 100644 test/Sema/builtins-ppc.c diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 7078cd8cdc..ddd693a1c9 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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); diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 35597fe4a0..90ca218a83 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -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(Ops[1]); - ConstantInt *CI2 = dyn_cast(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(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(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(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(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, ""); - } - } } diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index abcccbaf18..3e3d60e053 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -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 index 4408ab48a1..0000000000 --- a/test/CodeGen/builtins-ppc-crypto-diag.c +++ /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 - -#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 index 0000000000..60872a614e --- /dev/null +++ b/test/Sema/builtins-ppc.c @@ -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 + +#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 + -- 2.40.0