@@ -61,6 +61,11 @@ multiclass RVVOutBuiltinSet<string intrinsic_name, string type_range,
61
61
list<list<string>> suffixes_prototypes>
62
62
: RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1]>;
63
63
64
+ // IntrinsicTypes is output, op1 [-1, 0]
65
+ multiclass RVVOutOp0BuiltinSet<string intrinsic_name, string type_range,
66
+ list<list<string>> suffixes_prototypes>
67
+ : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 0]>;
68
+
64
69
// IntrinsicTypes is output, op1 [-1, 1]
65
70
multiclass RVVOutOp1BuiltinSet<string intrinsic_name, string type_range,
66
71
list<list<string>> suffixes_prototypes>
@@ -256,6 +261,29 @@ class RVVMaskOp0Builtin<string ir, string prototype> : RVVOp0Builtin<"m", protot
256
261
let HasMaskedOffOperand = false;
257
262
}
258
263
264
+ let HasMaskedOffOperand = true in {
265
+ multiclass RVVSignedReductionBuiltin {
266
+ defm "" : RVVOutOp0BuiltinSet<NAME, "csil",
267
+ [["vs", "vSv", "SvvSv"]]>;
268
+ }
269
+ multiclass RVVUnsignedReductionBuiltin {
270
+ defm "" : RVVOutOp0BuiltinSet<NAME, "csil",
271
+ [["vs", "UvUSv", "USvUvUSv"]]>;
272
+ }
273
+ multiclass RVVFloatingReductionBuiltin {
274
+ defm "" : RVVOutOp0BuiltinSet<NAME, "xfd",
275
+ [["vs", "vSv", "SvvSv"]]>;
276
+ }
277
+ multiclass RVVFloatingWidenReductionBuiltin {
278
+ defm "" : RVVOutOp0BuiltinSet<NAME, "xf",
279
+ [["vs", "vSw", "SwvSw"]]>;
280
+ }
281
+ }
282
+
283
+ multiclass RVVIntReductionBuiltinSet
284
+ : RVVSignedReductionBuiltin,
285
+ RVVUnsignedReductionBuiltin;
286
+
259
287
//===----------------------------------------------------------------------===//
260
288
// 6. Configuration-Setting and Utility
261
289
//===----------------------------------------------------------------------===//
@@ -1323,6 +1351,89 @@ let UnMaskedPolicyScheme = HasPassthruOperand,
1323
1351
defm th_vnclip : RVVSignedNShiftBuiltinSetRoundingMode;
1324
1352
}
1325
1353
1354
+
1355
+ // 15. Vector Reduction Operations
1356
+ // 15.1. Vector Single-Width Integer Reduction Instructions
1357
+ let UnMaskedPolicyScheme = HasPassthruOperand,
1358
+ MaskedPolicyScheme = HasPassthruOperand,
1359
+ HasMaskPolicy = false in {
1360
+ defm th_vredsum : RVVIntReductionBuiltinSet;
1361
+ defm th_vredmaxu : RVVUnsignedReductionBuiltin;
1362
+ defm th_vredmax : RVVSignedReductionBuiltin;
1363
+ defm th_vredminu : RVVUnsignedReductionBuiltin;
1364
+ defm th_vredmin : RVVSignedReductionBuiltin;
1365
+ defm th_vredand : RVVIntReductionBuiltinSet;
1366
+ defm th_vredor : RVVIntReductionBuiltinSet;
1367
+ defm th_vredxor : RVVIntReductionBuiltinSet;
1368
+
1369
+ // 15.2. Vector Widening Integer Reduction Instructions
1370
+ // Vector Widening Integer Reduction Operations
1371
+ let HasMaskedOffOperand = true in {
1372
+ defm th_vwredsum : RVVOutOp0BuiltinSet<"th_vwredsum", "csi",
1373
+ [["vs", "vSw", "SwvSw"]]>;
1374
+ defm th_vwredsumu : RVVOutOp0BuiltinSet<"th_vwredsumu", "csi",
1375
+ [["vs", "UvUSw", "USwUvUSw"]]>;
1376
+ }
1377
+
1378
+ // 15.3. Vector Single-Width Floating-Point Reduction Instructions
1379
+ defm th_vfredmax : RVVFloatingReductionBuiltin;
1380
+ defm th_vfredmin : RVVFloatingReductionBuiltin;
1381
+
1382
+ let ManualCodegen = [{
1383
+ {
1384
+ // LLVM intrinsic
1385
+ // Unmasked: (passthru, op0, op1, round_mode, vl)
1386
+ // Masked: (passthru, vector_in, vector_in/scalar_in, mask, frm, vl)
1387
+
1388
+ SmallVector<llvm::Value*, 7> Operands;
1389
+ bool HasMaskedOff = !(
1390
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
1391
+ (!IsMasked && PolicyAttrs & RVV_VTA));
1392
+ bool HasRoundModeOp = IsMasked ?
1393
+ (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) :
1394
+ (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
1395
+
1396
+ unsigned Offset = IsMasked ?
1397
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
1398
+
1399
+ if (!HasMaskedOff)
1400
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
1401
+ else
1402
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
1403
+
1404
+ Operands.push_back(Ops[Offset]); // op0
1405
+ Operands.push_back(Ops[Offset + 1]); // op1
1406
+
1407
+ if (IsMasked)
1408
+ Operands.push_back(Ops[0]); // mask
1409
+
1410
+ if (HasRoundModeOp) {
1411
+ Operands.push_back(Ops[Offset + 2]); // frm
1412
+ Operands.push_back(Ops[Offset + 3]); // vl
1413
+ } else {
1414
+ Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
1415
+ Operands.push_back(Ops[Offset + 2]); // vl
1416
+ }
1417
+
1418
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
1419
+ Ops.back()->getType()};
1420
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
1421
+ return Builder.CreateCall(F, Operands, "");
1422
+ }
1423
+ }] in {
1424
+ // NOTE: there's no RoundingMode version (like `vfredosum_*_rm`)
1425
+ // for floating point reduction in XTHeadVector.
1426
+
1427
+ // 15.3. Vector Single-Width Floating-Point Reduction Instructions
1428
+ defm th_vfredsum : RVVFloatingReductionBuiltin;
1429
+ defm th_vfredosum : RVVFloatingReductionBuiltin;
1430
+
1431
+ // 15.4. Vector Widening Floating-Point Reduction Instructions
1432
+ defm th_vfwredsum : RVVFloatingWidenReductionBuiltin;
1433
+ defm th_vfwredosum : RVVFloatingWidenReductionBuiltin;
1434
+ }
1435
+ }
1436
+
1326
1437
// 16. Vector Mask Instructions
1327
1438
1328
1439
// 16.1. Vector Mask-Register Logical Instructions
0 commit comments