@@ -66,6 +66,14 @@ translateX86ToMsvcIntrin(unsigned BuiltinID) {
66
66
llvm_unreachable (" must return from switch" );
67
67
}
68
68
69
+ // / Get integer from a mlir::Value that is an int constant or a constant op.
70
+ static int64_t getIntValueFromConstOp (mlir::Value val) {
71
+ auto constOp = mlir::cast<cir::ConstantOp>(val.getDefiningOp ());
72
+ return (mlir::cast<cir::IntAttr>(constOp.getValue ()))
73
+ .getValue ()
74
+ .getSExtValue ();
75
+ }
76
+
69
77
mlir::Value CIRGenFunction::emitX86BuiltinExpr (unsigned BuiltinID,
70
78
const CallExpr *E) {
71
79
if (BuiltinID == Builtin::BI__builtin_cpu_is)
@@ -96,7 +104,23 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID,
96
104
default :
97
105
return nullptr ;
98
106
case X86::BI_mm_prefetch: {
99
- llvm_unreachable (" _mm_prefetch NYI" );
107
+ mlir::Value Address = builder.createPtrBitcast (Ops[0 ], VoidTy);
108
+
109
+ int64_t Hint = getIntValueFromConstOp (Ops[1 ]);
110
+ mlir::Value RW = builder.create <cir::ConstantOp>(
111
+ getLoc (E->getExprLoc ()),
112
+ cir::IntAttr::get (SInt32Ty, (Hint >> 2 ) & 0x1 ));
113
+ mlir::Value Locality = builder.create <cir::ConstantOp>(
114
+ getLoc (E->getExprLoc ()), cir::IntAttr::get (SInt32Ty, Hint & 0x3 ));
115
+ mlir::Value Data = builder.create <cir::ConstantOp>(
116
+ getLoc (E->getExprLoc ()), cir::IntAttr::get (SInt32Ty, 1 ));
117
+ mlir::Type voidTy = cir::VoidType::get (&getMLIRContext ());
118
+
119
+ return builder
120
+ .create <cir::LLVMIntrinsicCallOp>(
121
+ getLoc (E->getExprLoc ()), builder.getStringAttr (" prefetch" ), voidTy,
122
+ mlir::ValueRange{Address, RW, Locality, Data})
123
+ .getResult ();
100
124
}
101
125
case X86::BI_mm_clflush: {
102
126
mlir::Type voidTy = cir::VoidType::get (&getMLIRContext ());
@@ -233,7 +257,23 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID,
233
257
case X86::BI__builtin_ia32_vec_set_v16hi:
234
258
case X86::BI__builtin_ia32_vec_set_v8si:
235
259
case X86::BI__builtin_ia32_vec_set_v4di: {
236
- llvm_unreachable (" __builtin_ia32_vec_set_vXX NYI" );
260
+ unsigned NumElts = cast<cir::VectorType>(Ops[0 ].getType ()).getSize ();
261
+
262
+ auto constOp = cast<cir::ConstantOp>(Ops[2 ].getDefiningOp ());
263
+ auto intAttr = cast<cir::IntAttr>(constOp.getValue ());
264
+ uint64_t index = intAttr.getValue ().getZExtValue ();
265
+
266
+ index &= NumElts - 1 ;
267
+
268
+ auto indexAttr = cir::IntAttr::get (
269
+ cir::IntType::get (&getMLIRContext (), 64 , false ), index);
270
+ auto indexVal =
271
+ builder.create <cir::ConstantOp>(getLoc (E->getExprLoc ()), indexAttr);
272
+
273
+ // These builtins exist so we can ensure the index is an ICE and in range.
274
+ // Otherwise we could just do this in the header file.
275
+ return builder.create <cir::VecInsertOp>(getLoc (E->getExprLoc ()), Ops[0 ],
276
+ Ops[1 ], indexVal);
237
277
}
238
278
case X86::BI_mm_setcsr:
239
279
case X86::BI__builtin_ia32_ldmxcsr: {
0 commit comments