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
