2121using namespace clang ;
2222using namespace clang ::CIRGen;
2323
24+ // / Get integer from a mlir::Value that is an int constant or a constant op.
25+ static int64_t getIntValueFromConstOp (mlir::Value val) {
26+ return val.getDefiningOp <cir::ConstantOp>().getIntValue ().getSExtValue ();
27+ }
28+
29+ static mlir::Value emitClFlush (CIRGenFunction& cgf,
30+ const CallExpr* e,
31+ mlir::Value& op) {
32+ mlir::Type voidTy = cir::VoidType::get (&cgf.getMLIRContext ());
33+ mlir::Location location = cgf.getLoc (e->getExprLoc ());
34+ return cgf.getBuilder ()
35+ .create <cir::LLVMIntrinsicCallOp>(
36+ location, cgf.getBuilder ().getStringAttr (" x86.sse2.clflush" ),
37+ voidTy, op)
38+ .getResult ();
39+ }
40+
41+ static mlir::Value emitPrefetch (CIRGenFunction& cgf,
42+ const CallExpr* e,
43+ mlir::Value& addr,
44+ int64_t hint) {
45+ CIRGenBuilderTy& builder = cgf.getBuilder ();
46+ mlir::Type voidTy = cir::VoidType::get (&cgf.getMLIRContext ());
47+ mlir::Type sInt32Ty = cir::IntType::get (&cgf.getMLIRContext (), 32 , true );
48+ mlir::Value address = builder.createPtrBitcast (addr, voidTy);
49+ mlir::Location location = cgf.getLoc (e->getExprLoc ());
50+ mlir::Value rw =
51+ cir::ConstantOp::create (builder, location,
52+ cir::IntAttr::get (sInt32Ty , (hint >> 2 ) & 0x1 ));
53+ mlir::Value locality =
54+ cir::ConstantOp::create (builder, location,
55+ cir::IntAttr::get (sInt32Ty , hint & 0x3 ));
56+ mlir::Value data = cir::ConstantOp::create (builder, location,
57+ cir::IntAttr::get (sInt32Ty , 1 ));
58+
59+ return cir::LLVMIntrinsicCallOp::create (
60+ builder, location,
61+ builder.getStringAttr (" prefetch" ), voidTy,
62+ mlir::ValueRange{address, rw, locality, data})
63+ .getResult ();
64+ }
65+
66+
2467mlir::Value CIRGenFunction::emitX86BuiltinExpr (unsigned builtinID,
2568 const CallExpr *e) {
2669 if (builtinID == Builtin::BI__builtin_cpu_is) {
@@ -43,11 +86,28 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
4386 // Find out if any arguments are required to be integer constant expressions.
4487 assert (!cir::MissingFeatures::handleBuiltinICEArguments ());
4588
89+ // The operands of the builtin call
90+ llvm::SmallVector<mlir::Value, 4 > ops;
91+
92+ // `ICEArguments` is a bitmap indicating whether the argument at the i-th bit
93+ // is required to be a constant integer expression.
94+ unsigned ICEArguments = 0 ;
95+ ASTContext::GetBuiltinTypeError error;
96+ getContext ().GetBuiltinType (builtinID, error, &ICEArguments);
97+ assert (error == ASTContext::GE_None && " Error while getting builtin type." );
98+
99+ const unsigned numArgs = e->getNumArgs ();
100+ for (unsigned i = 0 ; i != numArgs; i++) {
101+ ops.push_back (emitScalarOrConstFoldImmArg (ICEArguments, i, e));
102+ }
103+
46104 switch (builtinID) {
47105 default :
48106 return {};
49107 case X86::BI_mm_prefetch:
108+ return emitPrefetch (*this , e, ops[0 ], getIntValueFromConstOp (ops[1 ]));
50109 case X86::BI_mm_clflush:
110+ return emitClFlush (*this , e, ops[0 ]);
51111 case X86::BI_mm_lfence:
52112 case X86::BI_mm_pause:
53113 case X86::BI_mm_mfence:
0 commit comments