llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: mygitljf <details> <summary>Changes</summary> 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 --- Full diff: https://github.com/llvm/llvm-project/pull/202111.diff 2 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+13-6) - (modified) clang/test/CodeGen/PR32874.c (+10) ``````````diff 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 `````````` </details> https://github.com/llvm/llvm-project/pull/202111 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
