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

Reply via email to