https://github.com/zlfn updated https://github.com/llvm/llvm-project/pull/221477

>From 2f7d2c8829ea837e2a3d9083b94fb4ca82e4363e Mon Sep 17 00:00:00 2001
From: zlfn <[email protected]>
Date: Sun, 6 Sep 2026 03:20:04 +0900
Subject: [PATCH 1/2] [clang][CodeGen] Emit prefetch hints and frame address
 depth as i32

The hint operands of llvm.prefetch and the depth operand of
llvm.frameaddress and llvm.returnaddress are declared as i32, but clang
emitted the values at the width of the C argument's type.

Zero-extend or truncate them to i32 before building the intrinsic call.
The conversion is a no-op where the widths already match, and folds back
to a constant, since Sema already requires these arguments to be
constants in range.
---
 clang/lib/CodeGen/CGBuiltin.cpp               |  5 ++++-
 .../CodeGen/builtin-frame-address-arg-type.c  | 16 ++++++++++++++
 .../test/CodeGen/builtin-prefetch-arg-type.c  | 22 +++++++++++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGen/builtin-frame-address-arg-type.c
 create mode 100644 clang/test/CodeGen/builtin-prefetch-arg-type.c

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f4598a8a54e1b..034c1cbfbdc40 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4117,12 +4117,13 @@ 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);
+    RW = Builder.CreateZExtOrTrunc(RW, Int32Ty);
     Locality = (E->getNumArgs() > 2)
                    ? EmitScalarOrConstFoldImmArg(ICEArguments, 2, E)
                    : llvm::ConstantInt::get(Int32Ty, 3);
+    Locality = Builder.CreateZExtOrTrunc(Locality, Int32Ty);
     Value *Data = llvm::ConstantInt::get(Int32Ty, 1);
     Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType());
     Builder.CreateCall(F, {Address, RW, Locality, Data});
@@ -5135,6 +5136,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   case Builtin::BI__builtin_return_address: {
     Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
                                                    getContext().UnsignedIntTy);
+    Depth = Builder.CreateZExtOrTrunc(Depth, Int32Ty);
     Function *F =
         CGM.getIntrinsic(Intrinsic::returnaddress, {CGM.ProgramPtrTy});
     return RValue::get(Builder.CreateCall(F, Depth));
@@ -5147,6 +5149,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   case Builtin::BI__builtin_frame_address: {
     Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
                                                    getContext().UnsignedIntTy);
+    Depth = Builder.CreateZExtOrTrunc(Depth, Int32Ty);
     Function *F = CGM.getIntrinsic(Intrinsic::frameaddress, AllocaInt8PtrTy);
     return RValue::get(Builder.CreateCall(F, Depth));
   }
diff --git a/clang/test/CodeGen/builtin-frame-address-arg-type.c 
b/clang/test/CodeGen/builtin-frame-address-arg-type.c
new file mode 100644
index 0000000000000..91cd94ec32072
--- /dev/null
+++ b/clang/test/CodeGen/builtin-frame-address-arg-type.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple msp430 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple avr -emit-llvm %s -o - | FileCheck %s
+
+// The depth operand of these intrinsics is i32 regardless of the width of
+// unsigned int on the target.
+
+void *test_return_address(void) {
+  // CHECK: call{{.*}} @llvm.returnaddress.p{{[0-9]}}(i32 0)
+  return __builtin_return_address(0);
+}
+
+void *test_frame_address(void) {
+  // CHECK: call{{.*}} @llvm.frameaddress.p{{[0-9]}}(i32 0)
+  return __builtin_frame_address(0);
+}
diff --git a/clang/test/CodeGen/builtin-prefetch-arg-type.c 
b/clang/test/CodeGen/builtin-prefetch-arg-type.c
new file mode 100644
index 0000000000000..c2481f1e77dde
--- /dev/null
+++ b/clang/test/CodeGen/builtin-prefetch-arg-type.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple msp430 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple avr -emit-llvm %s -o - | FileCheck %s
+
+// The hint operands of llvm.prefetch are i32 regardless of the type of the
+// corresponding C argument, which is narrower on targets with a 16-bit int and
+// wider when the caller passes a long.
+
+void test_int(void *p) {
+  // CHECK: call{{.*}} void @llvm.prefetch.p0(ptr {{%.+}}, i32 1, i32 3, i32 1)
+  __builtin_prefetch(p, 1, 3);
+}
+
+void test_long(void *p) {
+  // CHECK: call{{.*}} void @llvm.prefetch.p0(ptr {{%.+}}, i32 1, i32 3, i32 1)
+  __builtin_prefetch(p, 1L, 3L);
+}
+
+void test_defaulted_hints(void *p) {
+  // CHECK: call{{.*}} void @llvm.prefetch.p0(ptr {{%.+}}, i32 0, i32 3, i32 1)
+  __builtin_prefetch(p);
+}

>From dfbe2a24a5533ccee72411e8c8727ff9f473b7d0 Mon Sep 17 00:00:00 2001
From: zlfn <[email protected]>
Date: Tue, 8 Sep 2026 14:51:43 +0900
Subject: [PATCH 2/2] [clang][Sema] Convert the __builtin_prefetch hints to int

Co-authored-by: mygitljf <[email protected]>
---
 clang/lib/Sema/SemaChecking.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index f0a1a529841b2..7814fe5ba2951 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6685,9 +6685,12 @@ 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))
-      return true;
+  for (unsigned i = 1; i != NumArgs; ++i) {
+      if (BuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))
+          return true;
+      if (convertArgumentToType(*this, TheCall->getArgs()[i], Context.IntTy))
+          return true;
+  }
 
   return false;
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to