-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[CIR] Upstream handling for __builtin_prefetch #164387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clangir Author: Shawn K (kimsh02) ChangesFix #163886 Full diff: https://github.com/llvm/llvm-project/pull/164387.diff 4 Files Affected:
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index e0163a4fecd5f..43abdc8f7bc0b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4049,6 +4049,39 @@ def CIR_ExpectOp : CIR_Op<"expect", [
}];
}
+//===----------------------------------------------------------------------===//
+// PrefetchOp
+//===----------------------------------------------------------------------===//
+
+def CIR_PrefetchOp : CIR_Op<"prefetch"> {
+ let summary = "prefetch operation";
+ let description = [{
+ The `cir.prefetch` op prefetches data from the memmory address.
+
+ ```mlir
+ cir.prefetch(%0 : !cir.ptr<!void>) locality(1) write
+ ```
+
+ This opcode has the three attributes:
+ 1. The $locality is a temporal locality specifier
+ ranging from (0) - no locality, to (3) - extremely local keep in cache.
+ 2. The $isWrite is the specifier determining if the prefetch is prepaired
+ for a 'read' or 'write'.
+ If $isWrite doesn't specified it means that prefetch is prepared for 'read'.
+ }];
+
+ let arguments = (ins CIR_VoidPtrType:$addr,
+ ConfinedAttr<I32Attr, [IntMinValue<0>, IntMaxValue<3>]>:$locality,
+ UnitAttr:$isWrite);
+
+ let assemblyFormat = [{
+ `(` $addr `:` qualified(type($addr)) `)`
+ `locality``(` $locality `)`
+ (`write` $isWrite^) : (`read`)?
+ attr-dict
+ }];
+}
+
//===----------------------------------------------------------------------===//
// PtrDiffOp
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index ea31871806bd7..2571a402f9676 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -454,6 +454,27 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
assert(!cir::MissingFeatures::coroSizeBuiltinCall());
return getUndefRValue(e->getType());
}
+ case Builtin::BI__builtin_prefetch: {
+ auto evaluateOperandAsInt = [&](const Expr *arg) {
+ Expr::EvalResult res;
+ [[maybe_unused]] bool evalSucceed =
+ arg->EvaluateAsInt(res, cgm.getASTContext());
+ assert(evalSucceed && "expression should be able to evaluate as int");
+ return res.Val.getInt().getZExtValue();
+ };
+
+ bool isWrite = false;
+ if (e->getNumArgs() > 1)
+ isWrite = evaluateOperandAsInt(e->getArg(1));
+
+ int locality = 0;
+ if (e->getNumArgs() > 2)
+ locality = evaluateOperandAsInt(e->getArg(2));
+
+ mlir::Value address = emitScalarExpr(e->getArg(0));
+ cir::PrefetchOp::create(builder, loc, address, locality, isWrite);
+ return RValue::get(nullptr);
+ }
}
// If this is an alias for a lib function (e.g. __builtin_sin), emit
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 0243bf120f396..47f9d79b30655 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1507,6 +1507,15 @@ static uint64_t getTypeSize(mlir::Type type, mlir::Operation &op) {
return llvm::divideCeil(layout.getTypeSizeInBits(type), 8);
}
+mlir::LogicalResult CIRToLLVMPrefetchOpLowering::matchAndRewrite(
+ cir::PrefetchOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ rewriter.replaceOpWithNewOp<mlir::LLVM::Prefetch>(
+ op, adaptor.getAddr(), adaptor.getIsWrite(), adaptor.getLocality(),
+ /*DataCache*/ 1);
+ return mlir::success();
+}
+
mlir::LogicalResult CIRToLLVMPtrDiffOpLowering::matchAndRewrite(
cir::PtrDiffOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/test/CIR/CodeGen/builtin_prefetech.c b/clang/test/CIR/CodeGen/builtin_prefetech.c
new file mode 100644
index 0000000000000..343d9a808ad68
--- /dev/null
+++ b/clang/test/CIR/CodeGen/builtin_prefetech.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o - | FileCheck %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s -check-prefix=LLVM
+
+void foo(void *a) {
+ __builtin_prefetch(a, 1, 1);
+}
+
+// CIR: cir.func dso_local @foo(%arg0: !cir.ptr<!void> loc({{.*}}))
+// CIR: [[PTR_ALLOC:%.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["a", init] {alignment = 8 : i64}
+// CIR: cir.store %arg0, [[PTR_ALLOC]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
+// CIR: [[PTR:%.*]] = cir.load{{.*}} [[PTR_ALLOC]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+// CIR: cir.prefetch([[PTR]] : !cir.ptr<!void>) locality(1) write
+// CIR: cir.return
+
+// LLVM: define dso_local void @foo(ptr [[ARG0:%.*]])
+// LLVM: [[PTR_ALLOC:%.*]] = alloca ptr, i64 1
+// LLVM: store ptr [[ARG0]], ptr [[PTR_ALLOC]]
+// LLVM: [[PTR:%.*]] = load ptr, ptr [[PTR_ALLOC]]
+// LLVM: call void @llvm.prefetch.p0(ptr [[PTR]], i32 1, i32 1, i32 1)
+// LLVM: ret void
|
@llvm/pr-subscribers-clang Author: Shawn K (kimsh02) ChangesFix #163886 Full diff: https://github.com/llvm/llvm-project/pull/164387.diff 4 Files Affected:
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index e0163a4fecd5f..43abdc8f7bc0b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4049,6 +4049,39 @@ def CIR_ExpectOp : CIR_Op<"expect", [
}];
}
+//===----------------------------------------------------------------------===//
+// PrefetchOp
+//===----------------------------------------------------------------------===//
+
+def CIR_PrefetchOp : CIR_Op<"prefetch"> {
+ let summary = "prefetch operation";
+ let description = [{
+ The `cir.prefetch` op prefetches data from the memmory address.
+
+ ```mlir
+ cir.prefetch(%0 : !cir.ptr<!void>) locality(1) write
+ ```
+
+ This opcode has the three attributes:
+ 1. The $locality is a temporal locality specifier
+ ranging from (0) - no locality, to (3) - extremely local keep in cache.
+ 2. The $isWrite is the specifier determining if the prefetch is prepaired
+ for a 'read' or 'write'.
+ If $isWrite doesn't specified it means that prefetch is prepared for 'read'.
+ }];
+
+ let arguments = (ins CIR_VoidPtrType:$addr,
+ ConfinedAttr<I32Attr, [IntMinValue<0>, IntMaxValue<3>]>:$locality,
+ UnitAttr:$isWrite);
+
+ let assemblyFormat = [{
+ `(` $addr `:` qualified(type($addr)) `)`
+ `locality``(` $locality `)`
+ (`write` $isWrite^) : (`read`)?
+ attr-dict
+ }];
+}
+
//===----------------------------------------------------------------------===//
// PtrDiffOp
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index ea31871806bd7..2571a402f9676 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -454,6 +454,27 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
assert(!cir::MissingFeatures::coroSizeBuiltinCall());
return getUndefRValue(e->getType());
}
+ case Builtin::BI__builtin_prefetch: {
+ auto evaluateOperandAsInt = [&](const Expr *arg) {
+ Expr::EvalResult res;
+ [[maybe_unused]] bool evalSucceed =
+ arg->EvaluateAsInt(res, cgm.getASTContext());
+ assert(evalSucceed && "expression should be able to evaluate as int");
+ return res.Val.getInt().getZExtValue();
+ };
+
+ bool isWrite = false;
+ if (e->getNumArgs() > 1)
+ isWrite = evaluateOperandAsInt(e->getArg(1));
+
+ int locality = 0;
+ if (e->getNumArgs() > 2)
+ locality = evaluateOperandAsInt(e->getArg(2));
+
+ mlir::Value address = emitScalarExpr(e->getArg(0));
+ cir::PrefetchOp::create(builder, loc, address, locality, isWrite);
+ return RValue::get(nullptr);
+ }
}
// If this is an alias for a lib function (e.g. __builtin_sin), emit
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 0243bf120f396..47f9d79b30655 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1507,6 +1507,15 @@ static uint64_t getTypeSize(mlir::Type type, mlir::Operation &op) {
return llvm::divideCeil(layout.getTypeSizeInBits(type), 8);
}
+mlir::LogicalResult CIRToLLVMPrefetchOpLowering::matchAndRewrite(
+ cir::PrefetchOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ rewriter.replaceOpWithNewOp<mlir::LLVM::Prefetch>(
+ op, adaptor.getAddr(), adaptor.getIsWrite(), adaptor.getLocality(),
+ /*DataCache*/ 1);
+ return mlir::success();
+}
+
mlir::LogicalResult CIRToLLVMPtrDiffOpLowering::matchAndRewrite(
cir::PtrDiffOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/test/CIR/CodeGen/builtin_prefetech.c b/clang/test/CIR/CodeGen/builtin_prefetech.c
new file mode 100644
index 0000000000000..343d9a808ad68
--- /dev/null
+++ b/clang/test/CIR/CodeGen/builtin_prefetech.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o - | FileCheck %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s -check-prefix=LLVM
+
+void foo(void *a) {
+ __builtin_prefetch(a, 1, 1);
+}
+
+// CIR: cir.func dso_local @foo(%arg0: !cir.ptr<!void> loc({{.*}}))
+// CIR: [[PTR_ALLOC:%.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["a", init] {alignment = 8 : i64}
+// CIR: cir.store %arg0, [[PTR_ALLOC]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
+// CIR: [[PTR:%.*]] = cir.load{{.*}} [[PTR_ALLOC]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+// CIR: cir.prefetch([[PTR]] : !cir.ptr<!void>) locality(1) write
+// CIR: cir.return
+
+// LLVM: define dso_local void @foo(ptr [[ARG0:%.*]])
+// LLVM: [[PTR_ALLOC:%.*]] = alloca ptr, i64 1
+// LLVM: store ptr [[ARG0]], ptr [[PTR_ALLOC]]
+// LLVM: [[PTR:%.*]] = load ptr, ptr [[PTR_ALLOC]]
+// LLVM: call void @llvm.prefetch.p0(ptr [[PTR]], i32 1, i32 1, i32 1)
+// LLVM: ret void
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for authoring this, some comments inline.
I'm still new to upstreaming, so thanks for your patience and all the feedback |
760e039
to
645ffaa
Compare
Getting this failed test case, not sure if I broke something.
|
That's totally expected. I appreciate your willingness to help. BTW, the CI failure was unrelated to your change and is fixed now. |
@andykaylor I merged again and looking at the build artifact for the build/test on Linux, and I think the failure is unrelated to my PR again? |
Yes. This one is because of an MLIR function that has been deprecated. That's fixed by this commit: #164656 I guess the CI runs using the commit that your PR is based on rather than trying to merge your PR onto the top of trunk. I'm rebasing a couple of other commits for this same reason. Normally I wouldn't worry about unrelated failures, but this one stops the build so none of the usual CI testing was done in this case. |
Actually, it looks like we missed some. I'll put up another PR to fix it. |
#164719 should fix the CI issues. And I think I was wrong about CI not merging with top of trunk. The problem was just that we still had deprecated calls in top of trunk. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Fix #163886