]> granicus.if.org Git - clang/commitdiff
Allow prefetching from non-zero address spaces
authorJF Bastien <jfbastien@apple.com>
Thu, 25 Jul 2019 16:11:57 +0000 (16:11 +0000)
committerJF Bastien <jfbastien@apple.com>
Thu, 25 Jul 2019 16:11:57 +0000 (16:11 +0000)
Summary:
This is useful for targets which have prefetch instructions for non-default address spaces.

<rdar://problem/42662136>

Subscribers: nemanjai, javed.absar, hiraditya, kbarton, jkorous, dexonsmith, cfe-commits, llvm-commits, RKSimon, hfinkel, t.p.northover, craig.topper, anemet

Tags: #clang, #llvm

Differential Revision: https://reviews.llvm.org/D65254

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@367032 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBuiltin.cpp
lib/Sema/SemaExpr.cpp
test/CodeGen/arm_acle.c
test/CodeGen/builtins-arm.c
test/CodeGen/builtins-arm64.c
test/CodeGen/ppc-xmmintrin.c
test/CodeGen/pr9614.c
test/CodeGen/prefetch-addr-spaces.c [new file with mode: 0644]
test/CodeGen/prefetchw-builtins.c
test/CodeGen/sse-builtins.c

index 82c089e722b871ba077560f4f5a0bba2e88c2fde..aaa196f80658ee80f1b01660612a6af80f621b95 100644 (file)
@@ -2133,7 +2133,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
     Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
       llvm::ConstantInt::get(Int32Ty, 3);
     Value *Data = llvm::ConstantInt::get(Int32Ty, 1);
-    Function *F = CGM.getIntrinsic(Intrinsic::prefetch);
+    Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType());
     return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data}));
   }
   case Builtin::BI__builtin_readcyclecounter: {
@@ -6021,7 +6021,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
     // Locality is not supported on ARM target
     Value *Locality = llvm::ConstantInt::get(Int32Ty, 3);
 
-    Function *F = CGM.getIntrinsic(Intrinsic::prefetch);
+    Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType());
     return Builder.CreateCall(F, {Address, RW, Locality, IsData});
   }
 
@@ -6960,7 +6960,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
 
     // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify
     // PLDL3STRM or PLDL2STRM.
-    Function *F = CGM.getIntrinsic(Intrinsic::prefetch);
+    Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType());
     return Builder.CreateCall(F, {Address, RW, Locality, IsData});
   }
 
@@ -10037,7 +10037,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
     Value *RW = ConstantInt::get(Int32Ty, (C->getZExtValue() >> 2) & 0x1);
     Value *Locality = ConstantInt::get(Int32Ty, C->getZExtValue() & 0x3);
     Value *Data = ConstantInt::get(Int32Ty, 1);
-    Function *F = CGM.getIntrinsic(Intrinsic::prefetch);
+    Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType());
     return Builder.CreateCall(F, {Address, RW, Locality, Data});
   }
   case X86::BI_mm_clflush: {
index 401bb3c000b6db586c7b075193cd31418f13d9c6..8f5a892b9a2e6c84490890b5dd2afa83adbfa2e0 100644 (file)
@@ -5375,8 +5375,8 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context,
   QualType DeclType = FDecl->getType();
   const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(DeclType);
 
-  if (!Context.BuiltinInfo.hasPtrArgsOrResult(FDecl->getBuiltinID()) ||
-      !FT || FT->isVariadic() || ArgExprs.size() != FT->getNumParams())
+  if (!Context.BuiltinInfo.hasPtrArgsOrResult(FDecl->getBuiltinID()) || !FT ||
+      ArgExprs.size() < FT->getNumParams())
     return nullptr;
 
   bool NeedsNewDecl = false;
@@ -5415,6 +5415,7 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context,
     return nullptr;
 
   FunctionProtoType::ExtProtoInfo EPI;
+  EPI.Variadic = FT->isVariadic();
   QualType OverloadTy = Context.getFunctionType(FT->getReturnType(),
                                                 OverloadParams, EPI);
   DeclContext *Parent = FDecl->getParent();
index beca9373506781d76a986116b647224ceca62b88..2f086ee70bfd9a2cd9f37e560cdc298f2ae362ef 100644 (file)
@@ -88,28 +88,28 @@ void test_swp(uint32_t x, volatile void *p) {
 /* 8.6 Memory prefetch intrinsics */
 /* 8.6.1 Data prefetch */
 // ARM-LABEL: test_pld
-// ARM: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 1)
+// ARM: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 1)
 void test_pld() {
   __pld(0);
 }
 
 // ARM-LABEL: test_pldx
-// AArch32: call void @llvm.prefetch(i8* null, i32 1, i32 3, i32 1)
-// AArch64: call void @llvm.prefetch(i8* null, i32 1, i32 1, i32 1)
+// AArch32: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 3, i32 1)
+// AArch64: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 1, i32 1)
 void test_pldx() {
   __pldx(1, 2, 0, 0);
 }
 
 /* 8.6.2 Instruction prefetch */
 // ARM-LABEL: test_pli
-// ARM: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 0)
+// ARM: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0)
 void test_pli() {
   __pli(0);
 }
 
 // ARM-LABEL: test_plix
-// AArch32: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 0)
-// AArch64: call void @llvm.prefetch(i8* null, i32 0, i32 1, i32 0)
+// AArch32: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0)
+// AArch64: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 1, i32 0)
 void test_plix() {
   __plix(2, 0, 0);
 }
index 020f2b4dc528d50f7111d1c0f3a7a8f5ef943118..4941411bfbbb22651c12864626f2121ca9e1b83b 100644 (file)
@@ -92,14 +92,13 @@ unsigned rbit(unsigned a) {
 
 void prefetch(int i) {
   __builtin_arm_prefetch(&i, 0, 1);
-// CHECK: call {{.*}} @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 1)
+  // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* %{{.*}}, i32 0, i32 3, i32 1)
 
   __builtin_arm_prefetch(&i, 1, 1);
-// CHECK: call {{.*}} @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 1)
-
+  // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* %{{.*}}, i32 1, i32 3, i32 1)
 
   __builtin_arm_prefetch(&i, 1, 0);
-// CHECK: call {{.*}} @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 0)
+  // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* %{{.*}}, i32 1, i32 3, i32 0)
 }
 
 void ldc(const void *i) {
index 5ec63fba82b5bbbbdc944fca85919ba67d31086f..7095396e6bb348d33a0fd7f77f6bdddfdd6e29eb 100644 (file)
@@ -46,16 +46,16 @@ void barriers() {
 
 void prefetch() {
   __builtin_arm_prefetch(0, 1, 2, 0, 1); // pstl3keep
-// CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 1, i32 1, i32 1)
+  // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* null, i32 1, i32 1, i32 1)
 
   __builtin_arm_prefetch(0, 0, 0, 1, 1); // pldl1keep
-// CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 0, i32 0, i32 1)
+  // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* null, i32 0, i32 0, i32 1)
 
   __builtin_arm_prefetch(0, 0, 0, 1, 1); // pldl1strm
-// CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 0, i32 0, i32 1)
+  // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* null, i32 0, i32 0, i32 1)
 
   __builtin_arm_prefetch(0, 0, 0, 0, 0); // plil1keep
-// CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 0, i32 3, i32 0)
+  // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0)
 }
 
 int32_t jcvt(double v) {
index fd81937da637e6c7ef8a60170aa9c6b041005342..094f18efcb628949cdc97f2092eeb04b013fc30a 100644 (file)
@@ -1435,7 +1435,7 @@ test_prefetch() {
 // CHECK: store i8* {{[0-9a-zA-Z_%.]+}}, i8** {{[0-9a-zA-Z_%.]+}}, align 8
 // CHECK-NEXT: store i32 {{[0-9a-zA-Z_%.]+}}, i32* {{[0-9a-zA-Z_%.]+}}, align 4
 // CHECK-NEXT: [[REG715:[0-9a-zA-Z_%.]+]] = load i8*, i8** {{[0-9a-zA-Z_%.]+}}, align 8
-// CHECK-NEXT: call void @llvm.prefetch(i8* [[REG715]], i32 0, i32 3, i32 1)
+// CHECK-NEXT: call void @llvm.prefetch.p0i8(i8* [[REG715]], i32 0, i32 3, i32 1)
 // CHECK-NEXT: ret void
 
 void __attribute__((noinline))
index 63cb5af1868c1bb5da151ead94ef658e61089dd1..08089848eeba129d24f7fcfb3deea9d7e7e1398b 100644 (file)
@@ -34,7 +34,7 @@ void f(void) {
 // CHECK: call void @foo()
 // CHECK: call i32 @abs(i32 0)
 // CHECK: call i8* @strrchr(
-// CHECK: call void @llvm.prefetch(
+// CHECK: call void @llvm.prefetch.p0i8(
 // CHECK: call i8* @memchr(
 // CHECK: ret void
 
@@ -42,4 +42,4 @@ void f(void) {
 // CHECK: declare i32 @abs(i32
 // CHECK: declare i8* @strrchr(i8*, i32)
 // CHECK: declare i8* @memchr(
-// CHECK: declare void @llvm.prefetch(
+// CHECK: declare void @llvm.prefetch.p0i8(
diff --git a/test/CodeGen/prefetch-addr-spaces.c b/test/CodeGen/prefetch-addr-spaces.c
new file mode 100644 (file)
index 0000000..8781062
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck %s
+
+void f(int __attribute__((address_space(1))) * a, ...) {
+  __builtin_prefetch(a, 0, 1);
+  // CHECK: call void @llvm.prefetch.p1i8(i8 addrspace(1)* {{%.+}}, i32 0, i32 1, i32 1)
+}
index 53416de46ff470a681b101f0392a10f2d70b1ba6..b3a8062acf659745eeae73f47cb9c888d52de5a2 100644 (file)
@@ -5,12 +5,12 @@
 
 void test_m_prefetch(void *p) {
   return _m_prefetch(p);
-// CHECK-LABEL: define void @test_m_prefetch
-// CHECK: call void @llvm.prefetch({{.*}}, i32 0, i32 3, i32 1)
+  // CHECK-LABEL: define void @test_m_prefetch
+  // CHECK: call void @llvm.prefetch.p0i8({{.*}}, i32 0, i32 3, i32 1)
 }
 
 void test_m_prefetch_w(void *p) {
   return _m_prefetchw(p);
-// CHECK-LABEL: define void @test_m_prefetch_w
-// CHECK: call void @llvm.prefetch({{.*}}, i32 1, i32 3, i32 1)
+  // CHECK-LABEL: define void @test_m_prefetch_w
+  // CHECK: call void @llvm.prefetch.p0i8({{.*}}, i32 1, i32 3, i32 1)
 }
index 4179341fadfc0d5368cec67f99f059661ffb1686..b68a714b43b3429b45924d739256fdec4a107d87 100644 (file)
@@ -503,7 +503,7 @@ __m128 test_mm_or_ps(__m128 A, __m128 B) {
 
 void test_mm_prefetch(char const* p) {
   // CHECK-LABEL: test_mm_prefetch
-  // CHECK: call void @llvm.prefetch(i8* {{.*}}, i32 0, i32 0, i32 1)
+  // CHECK: call void @llvm.prefetch.p0i8(i8* {{.*}}, i32 0, i32 0, i32 1)
   _mm_prefetch(p, 0);
 }