Author: Nikita Popov
Date: 2026-09-15T14:15:11+02:00
New Revision: 3a42f8a335269c4d01274f8b04057fa66c87d969

URL: 
https://github.com/llvm/llvm-project/commit/3a42f8a335269c4d01274f8b04057fa66c87d969
DIFF: 
https://github.com/llvm/llvm-project/commit/3a42f8a335269c4d01274f8b04057fa66c87d969.diff

LOG: [ARM] Emit llvm.clear_cache for __clear_cache() (#223398)

It looks like the ARM-specific __clear_cache() builtin emits different
IR than the generic __builtin___clear_cache() builtin (added later),
which uses the llvm.clear_cache intrinsic (which will typically lower to
a __clear_cache libcall, of course).

Use llvm.clear_cache for __clear_cache() as well, for consistency and to
slightly simplify the code.

Added: 
    

Modified: 
    clang/lib/CodeGen/TargetBuiltins/ARM.cpp
    clang/test/CodeGen/builtins-arm.c
    clang/test/CodeGen/builtins-arm64.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp 
b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
index 36b87db7ee1f5..527bfd752e018 100644
--- a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
@@ -2170,15 +2170,10 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned 
BuiltinID,
   }
 
   if (BuiltinID == clang::ARM::BI__clear_cache) {
-    assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
-    const FunctionDecl *FD = E->getDirectCallee();
-    Value *Ops[2];
-    for (unsigned i = 0; i < 2; i++)
-      Ops[i] = EmitScalarExpr(E->getArg(i));
-    llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
-    llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
-    StringRef Name = FD->getName();
-    return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
+    Value *Begin = EmitScalarExpr(E->getArg(0));
+    Value *End = EmitScalarExpr(E->getArg(1));
+    Function *F = CGM.getIntrinsic(Intrinsic::clear_cache, {CGM.DefaultPtrTy});
+    return Builder.CreateCall(F, {Begin, End});
   }
 
   if (BuiltinID == clang::ARM::BI__builtin_arm_mcrr ||
@@ -4618,15 +4613,10 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned 
BuiltinID,
   }
 
   if (BuiltinID == clang::AArch64::BI__clear_cache) {
-    assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
-    const FunctionDecl *FD = E->getDirectCallee();
-    Value *Ops[2];
-    for (unsigned i = 0; i < 2; i++)
-      Ops[i] = EmitScalarExpr(E->getArg(i));
-    llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
-    llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
-    StringRef Name = FD->getName();
-    return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
+    Value *Begin = EmitScalarExpr(E->getArg(0));
+    Value *End = EmitScalarExpr(E->getArg(1));
+    Function *F = CGM.getIntrinsic(Intrinsic::clear_cache, {CGM.DefaultPtrTy});
+    return Builder.CreateCall(F, {Begin, End});
   }
 
   if ((BuiltinID == clang::AArch64::BI__builtin_arm_ldrex ||

diff  --git a/clang/test/CodeGen/builtins-arm.c 
b/clang/test/CodeGen/builtins-arm.c
index 3a72eebeae5de..862215b5d59ef 100644
--- a/clang/test/CodeGen/builtins-arm.c
+++ b/clang/test/CodeGen/builtins-arm.c
@@ -8,7 +8,7 @@ void *f0(void)
 }
 
 void f1(char *a, char *b) {
-  // CHECK: call {{.*}} @__clear_cache
+  // CHECK: call {{.*}} @llvm.clear_cache.p0
        __clear_cache(a,b);
 }
 

diff  --git a/clang/test/CodeGen/builtins-arm64.c 
b/clang/test/CodeGen/builtins-arm64.c
index 3d054c79f1777..f67a4a142b898 100644
--- a/clang/test/CodeGen/builtins-arm64.c
+++ b/clang/test/CodeGen/builtins-arm64.c
@@ -5,7 +5,7 @@
 
 void f0(void *a, void *b) {
        __clear_cache(a,b);
-// CHECK: call {{.*}} @__clear_cache
+// CHECK: call {{.*}} @llvm.clear_cache.p0
 }
 
 void *tp (void) {


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

Reply via email to