From 18f3a14e1328c813fa5dbacc9bb931d22f0669cd Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 10 May 2021 11:30:45 -0700 Subject: [PATCH] [RISCV] Validate the SEW and LMUL operands to __builtin_rvv_vsetvli(max) These are required to be constants, this patch makes sure they are in the accepted range of values. These are usually created by wrappers in the riscv_vector.h header which should always be correct. This patch protects against a user using the builtin directly. Reviewed By: khchen Differential Revision: https://reviews.llvm.org/D102086 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/include/clang/Sema/Sema.h | 1 + clang/lib/Sema/SemaChecking.cpp | 34 +++++++++++++++++++++++- clang/test/CodeGen/RISCV/rvv_errors.c | 10 +++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGen/RISCV/rvv_errors.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 99b4169..f78940a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11267,4 +11267,6 @@ def warn_tcb_enforcement_violation : Warning< // RISC-V builtin required extension warning def err_riscv_builtin_requires_extension : Error< "builtin requires '%0' extension support to be enabled">; +def err_riscv_builtin_invalid_lmul : Error< + "LMUL argument must be in the range [0,3] or [5,7]">; } // end of sema component. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d2a0745..53ff0f1 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12539,6 +12539,7 @@ private: bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index fec02b8..f3f1ccd 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3417,6 +3417,26 @@ bool Sema::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, return false; } +bool Sema::CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum) { + llvm::APSInt Result; + + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) + return true; + + int64_t Val = Result.getSExtValue(); + if ((Val >= 0 && Val <= 3) || (Val >= 5 && Val <= 7)) + return false; + + return Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_invalid_lmul) + << Arg->getSourceRange(); +} + bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall) { @@ -3448,7 +3468,19 @@ bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, << TheCall->getSourceRange() << StringRef(FeatureStr); } - return FeatureMissing; + if (FeatureMissing) + return true; + + switch (BuiltinID) { + case RISCV::BI__builtin_rvv_vsetvli: + return SemaBuiltinConstantArgRange(TheCall, 1, 0, 3) || + CheckRISCVLMUL(TheCall, 2); + case RISCV::BI__builtin_rvv_vsetvlimax: + return SemaBuiltinConstantArgRange(TheCall, 0, 0, 3) || + CheckRISCVLMUL(TheCall, 1); + } + + return false; } bool Sema::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, diff --git a/clang/test/CodeGen/RISCV/rvv_errors.c b/clang/test/CodeGen/RISCV/rvv_errors.c new file mode 100644 index 0000000..40ec544 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv_errors.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -triple=riscv64 -target-feature +experimental-v -fsyntax-only -verify + +void test() { + __builtin_rvv_vsetvli(1, 7, 0); // expected-error {{argument value 7 is outside the valid range [0, 3]}} + __builtin_rvv_vsetvlimax(-1, 0); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}} + __builtin_rvv_vsetvli(1, 0, 4); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}} + __builtin_rvv_vsetvlimax(0, 4); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}} + __builtin_rvv_vsetvli(1, 0, 8); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}} + __builtin_rvv_vsetvlimax(0, -1); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}} +} -- 2.7.4