[clang] [Clang] Fix incorrect handling of #pragma {GCC} unroll N in dependent context (PR #90240)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 26 10:52:53 PDT 2024
https://github.com/yronglin updated https://github.com/llvm/llvm-project/pull/90240
>From 131783211a23d007b5b6f1d5691306df4dec716b Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Sat, 27 Apr 2024 01:38:34 +0800
Subject: [PATCH 1/2] [Clang] Fix incorrect handling of #pragma {GCC} unroll N
in dependent context
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
clang/lib/Sema/SemaStmtAttr.cpp | 23 ++++++++++--------
clang/test/Parser/pragma-unroll.cpp | 37 +++++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 10 deletions(-)
diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp
index 9d44c22c8ddcc3..4dfdfd7aec425f 100644
--- a/clang/lib/Sema/SemaStmtAttr.cpp
+++ b/clang/lib/Sema/SemaStmtAttr.cpp
@@ -109,16 +109,19 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A,
SetHints(LoopHintAttr::Unroll, LoopHintAttr::Disable);
} else if (PragmaName == "unroll") {
// #pragma unroll N
- if (ValueExpr && !ValueExpr->isValueDependent()) {
- llvm::APSInt ValueAPS;
- ExprResult R = S.VerifyIntegerConstantExpression(ValueExpr, &ValueAPS);
- assert(!R.isInvalid() && "unroll count value must be a valid value, it's "
- "should be checked in Sema::CheckLoopHintExpr");
- (void)R;
- // The values of 0 and 1 block any unrolling of the loop.
- if (ValueAPS.isZero() || ValueAPS.isOne())
- SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Disable);
- else
+ if (ValueExpr) {
+ if (!ValueExpr->isValueDependent()) {
+ llvm::APSInt ValueAPS;
+ ExprResult R = S.VerifyIntegerConstantExpression(ValueExpr, &ValueAPS);
+ assert(!R.isInvalid() && "unroll count value must be a valid value, it's "
+ "should be checked in Sema::CheckLoopHintExpr");
+ (void)R;
+ // The values of 0 and 1 block any unrolling of the loop.
+ if (ValueAPS.isZero() || ValueAPS.isOne())
+ SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Disable);
+ else
+ SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Numeric);
+ } else
SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Numeric);
} else
SetHints(LoopHintAttr::Unroll, LoopHintAttr::Enable);
diff --git a/clang/test/Parser/pragma-unroll.cpp b/clang/test/Parser/pragma-unroll.cpp
index f41bd7a18d5a41..e84f6ea9ad1035 100644
--- a/clang/test/Parser/pragma-unroll.cpp
+++ b/clang/test/Parser/pragma-unroll.cpp
@@ -124,3 +124,40 @@ void test(int *List, int Length) {
#pragma unroll
/* expected-error {{expected statement}} */ }
+
+using size_t = unsigned long long;
+
+template <bool Flag>
+int FailToBuild(int n) {
+ constexpr int N = 100;
+ auto init = [=]() { return Flag ? n : 0UL; };
+ auto cond = [=](size_t ix) { return Flag ? ix != 0 : ix < 10; };
+ auto iter = [=](size_t ix) {
+ return Flag ? ix & ~(1ULL << __builtin_clzll(ix)) : ix + 1;
+ };
+#pragma unroll Flag ? 1 : N
+ for (size_t ix = init(); cond(ix); ix = iter(ix)) {
+ n *= n;
+ }
+#pragma unroll Flag ? 0 : N
+ for (size_t ix = init(); cond(ix); ix = iter(ix)) {
+ n *= n;
+ }
+#pragma GCC unroll Flag ? 1 : N
+ for (size_t ix = init(); cond(ix); ix = iter(ix)) {
+ n *= n;
+ }
+#pragma GCC unroll Flag ? 0 : N
+ for (size_t ix = init(); cond(ix); ix = iter(ix)) {
+ n *= n;
+ }
+ return n;
+}
+
+int foo(int n) {
+ return FailToBuild<true>(n);
+}
+
+int bar(int n) {
+ return FailToBuild<false>(n);
+}
>From 3e5ef859c3d55830199a366edf48a8f536dc1208 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Sat, 27 Apr 2024 01:52:41 +0800
Subject: [PATCH 2/2] Format
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
clang/lib/Sema/SemaStmtAttr.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp
index 4dfdfd7aec425f..d3e76f282974e9 100644
--- a/clang/lib/Sema/SemaStmtAttr.cpp
+++ b/clang/lib/Sema/SemaStmtAttr.cpp
@@ -113,8 +113,9 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A,
if (!ValueExpr->isValueDependent()) {
llvm::APSInt ValueAPS;
ExprResult R = S.VerifyIntegerConstantExpression(ValueExpr, &ValueAPS);
- assert(!R.isInvalid() && "unroll count value must be a valid value, it's "
- "should be checked in Sema::CheckLoopHintExpr");
+ assert(!R.isInvalid() &&
+ "unroll count value must be a valid value, it's "
+ "should be checked in Sema::CheckLoopHintExpr");
(void)R;
// The values of 0 and 1 block any unrolling of the loop.
if (ValueAPS.isZero() || ValueAPS.isOne())
More information about the cfe-commits
mailing list