https://github.com/mygitljf created https://github.com/llvm/llvm-project/pull/202111
I fixed a Clang CodeGen crash where valid __builtin_prefetch calls using non-int constant expressions, like sizeof or ULL constants, could produce LLVM IR arguments with the wrong type. The optional prefetch arguments are already checked by Sema as small integer constants, so this change lowers them directly as i32 constants to match llvm.prefetch’s immarg signature. I also added a regression test covering sizeof and unsigned long long constants. Fixes #202061 >From 7e93143f648172ab7f47cca66ea36d37584b6a9f Mon Sep 17 00:00:00 2001 From: mygitljf <[email protected]> Date: Sun, 7 Jun 2026 07:49:54 +0000 Subject: [PATCH] [clang] Emit i32 prefetch args --- clang/lib/CodeGen/CGBuiltin.cpp | 19 +++++++++++++------ clang/test/CodeGen/PR32874.c | 10 ++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 0cb5f95049789..1ce216d115501 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -4304,12 +4304,19 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(Result); } case Builtin::BI__builtin_prefetch: { - Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); - // FIXME: Technically these constants should of type 'int', yes? - RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : - llvm::ConstantInt::get(Int32Ty, 0); - Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : - llvm::ConstantInt::get(Int32Ty, 3); + auto EmitI32ConstArg = [&](unsigned ArgNo, uint64_t Default) -> Value * { + if (E->getNumArgs() <= ArgNo) + return llvm::ConstantInt::get(Int32Ty, Default); + + std::optional<llvm::APSInt> Result = + E->getArg(ArgNo)->getIntegerConstantExpr(getContext()); + assert(Result && "Expected argument to be a constant"); + return llvm::ConstantInt::get(Int32Ty, Result->getZExtValue()); + }; + + Value *Address = EmitScalarExpr(E->getArg(0)); + Value *RW = EmitI32ConstArg(1, 0); + Value *Locality = EmitI32ConstArg(2, 3); Value *Data = llvm::ConstantInt::get(Int32Ty, 1); Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType()); Builder.CreateCall(F, {Address, RW, Locality, Data}); 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
