[clang] [clang] Emit i32 args for __builtin_prefetch (PR #202111)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 15 19:50:57 PDT 2026
https://github.com/mygitljf updated https://github.com/llvm/llvm-project/pull/202111
>From e91ba5cc2caca2209d576715bbedc12d242dfceb Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Sun, 7 Jun 2026 07:49:54 +0000
Subject: [PATCH 1/2] [clang] Emit i32 prefetch args
---
clang/lib/CodeGen/CGBuiltin.cpp | 1 -
clang/lib/Sema/SemaChecking.cpp | 7 ++++++-
clang/test/CodeGen/PR32874.c | 10 ++++++++++
3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 682b125890fe1..17c3b9d97e4c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4289,7 +4289,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_prefetch: {
Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
unsigned ICEArguments = (1 << 1) | (1 << 2);
- // FIXME: Technically these constants should of type 'int', yes?
RW = (E->getNumArgs() > 1) ? EmitScalarOrConstFoldImmArg(ICEArguments, 1, E)
: llvm::ConstantInt::get(Int32Ty, 0);
Locality = (E->getNumArgs() > 2)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5e5fcb39905d6..6fec6468d87b2 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6492,10 +6492,15 @@ bool Sema::BuiltinPrefetch(CallExpr *TheCall) {
// Argument 0 is checked for us and the remaining arguments must be
// constant integers.
- for (unsigned i = 1; i != NumArgs; ++i)
+ for (unsigned i = 1; i != NumArgs; ++i) {
if (BuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))
return true;
+ ExprResult Arg =
+ ImpCastExprToType(TheCall->getArg(i), Context.IntTy, CK_IntegralCast);
+ TheCall->setArg(i, Arg.get());
+ }
+
return false;
}
diff --git a/clang/test/CodeGen/PR32874.c b/clang/test/CodeGen/PR32874.c
index 234eebcbe4574..665b327528b0a 100644
--- a/clang/test/CodeGen/PR32874.c
+++ b/clang/test/CodeGen/PR32874.c
@@ -23,6 +23,16 @@ void foo(const int *p) {
__builtin_prefetch(p, 3U % 2U, 3U % 1U);
}
+// CHECK-LABEL: define{{.*}} void @prefetch_non_int_constant_types
+// CHECK: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1)
+// CHECK: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 0, i32 1)
+// CHECK: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1)
+void prefetch_non_int_constant_types(const int *p) {
+ __builtin_prefetch(p, 0 * sizeof(int));
+ __builtin_prefetch(p, 0, 0 * sizeof(int));
+ __builtin_prefetch(p, 1ULL, 3ULL);
+}
+
// CHECK-LABEL: define{{.*}} void @ub_constant_arithmetic
void ub_constant_arithmetic(void) {
// Check that we still instrument unsafe arithmetic, even if it is known to
>From 52f24882a63f496e02a585694b169605064a5434 Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Thu, 16 Jul 2026 10:49:39 +0800
Subject: [PATCH 2/2] [clang] Convert prefetch arguments before range checking
---
clang/lib/Sema/SemaChecking.cpp | 9 +++++----
clang/test/Sema/builtin-prefetch.c | 2 +-
clang/test/SemaCXX/prefetch-enum.cpp | 10 ++++++++++
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 6fec6468d87b2..e7c5b38f7e799 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6493,12 +6493,13 @@ bool Sema::BuiltinPrefetch(CallExpr *TheCall) {
// Argument 0 is checked for us and the remaining arguments must be
// constant integers.
for (unsigned i = 1; i != NumArgs; ++i) {
- if (BuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))
+ Expr *Arg = TheCall->getArg(i);
+ if (convertArgumentToType(*this, Arg, Context.IntTy))
return true;
+ TheCall->setArg(i, Arg);
- ExprResult Arg =
- ImpCastExprToType(TheCall->getArg(i), Context.IntTy, CK_IntegralCast);
- TheCall->setArg(i, Arg.get());
+ if (BuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))
+ return true;
}
return false;
diff --git a/clang/test/Sema/builtin-prefetch.c b/clang/test/Sema/builtin-prefetch.c
index 16029b60690f6..521c0d975cfbe 100644
--- a/clang/test/Sema/builtin-prefetch.c
+++ b/clang/test/Sema/builtin-prefetch.c
@@ -6,7 +6,7 @@ void foo(void) {
__builtin_prefetch(&a, 1);
__builtin_prefetch(&a, 1, 2);
__builtin_prefetch(&a, 1, 9, 3); // expected-error{{too many arguments to function}}
- __builtin_prefetch(&a, "hello", 2); // expected-error{{argument to '__builtin_prefetch' must be a constant integer}}
+ __builtin_prefetch(&a, "hello", 2); // expected-error{{incompatible pointer to integer conversion passing 'char *' to parameter of type 'int'}} expected-error{{argument to '__builtin_prefetch' must be a constant integer}}
__builtin_prefetch(&a, a, 2); // expected-error{{argument to '__builtin_prefetch' must be a constant integer}}
__builtin_prefetch(&a, 2); // expected-error{{argument value 2 is outside the valid range [0, 1]}}
__builtin_prefetch(&a, 0, 4); // expected-error{{argument value 4 is outside the valid range [0, 3]}}
diff --git a/clang/test/SemaCXX/prefetch-enum.cpp b/clang/test/SemaCXX/prefetch-enum.cpp
index 5457bbe498fff..f0f481c33a56e 100644
--- a/clang/test/SemaCXX/prefetch-enum.cpp
+++ b/clang/test/SemaCXX/prefetch-enum.cpp
@@ -4,7 +4,17 @@
enum X { A = 3 };
+struct ReadWrite {
+ constexpr operator int() const { return 1; }
+};
+
+struct Locality {
+ constexpr operator int() const { return 3; }
+};
+
void Test() {
char ch;
__builtin_prefetch(&ch, 0, A);
+ __builtin_prefetch(&ch, ReadWrite());
+ __builtin_prefetch(&ch, 0, Locality());
}
More information about the cfe-commits
mailing list