@@ -420,191 +420,6 @@ LogicalResult ShuffleOp::verify() {
420
420
return success ();
421
421
}
422
422
423
- // ===----------------------------------------------------------------------===//
424
- // MulElemOp and FMAElemOp
425
- // ===----------------------------------------------------------------------===//
426
-
427
- // MulElemOp and FMAElemOp are structurally similar, except that FMAElem op
428
- // has few extra fields (accumulator, bool flag to indicate if it is fmsub,
429
- // etc.). We create some specializations to print those fields specifically for
430
- // FMAElemOp and MULElemOp.
431
-
432
- // Print the accumulator
433
- template <typename T>
434
- void printAccumulator (OpAsmPrinter &p, T op);
435
- template <>
436
- inline void printAccumulator (OpAsmPrinter &p, aievec::FMAElemOp op) {
437
- p << " , " << op.getAcc ();
438
- }
439
- template <>
440
- inline void printAccumulator (OpAsmPrinter &p, aievec::MulElemOp op) {}
441
-
442
- // Mark fmsub indicator as elided if the FMAElem op is not fmsub
443
- template <typename T>
444
- void elideFMSubAttr (T op, SmallVector<StringRef, 4 > &elidedAttrs);
445
- template <>
446
- inline void elideFMSubAttr (aievec::FMAElemOp op,
447
- SmallVector<StringRef, 4 > &elidedAttrs) {
448
- if (!op.getFmsub ()) elidedAttrs.push_back (op.getSubAttrName ());
449
- }
450
-
451
- template <>
452
- inline void elideFMSubAttr (aievec::MulElemOp op,
453
- SmallVector<StringRef, 4 > &elidedAttrs) {}
454
-
455
- // Print out MulElem and FMAElem op.
456
- template <typename T>
457
- static void printMulFMAElemOp (OpAsmPrinter &p, T op) {
458
- // Print the left operand
459
- p << " " << op.getLhs ();
460
- // Print the right operand
461
- p << " , " << op.getRhs ();
462
- // For fma op, print the accumulator
463
- printAccumulator (p, op);
464
-
465
- // Print the attributes, but don't print attributes that are empty strings
466
- SmallVector<StringRef, 4 > elidedAttrs;
467
- for (int idx = 0 ; idx < 2 ; ++idx) {
468
- elideFMSubAttr (op, elidedAttrs);
469
- }
470
- p.printOptionalAttrDict (op->getAttrs (), elidedAttrs);
471
-
472
- // And now print the types
473
- p << " : " << op.getLhs ().getType () << " , " << op.getRhs ().getType ();
474
- p << " , " << op.getResult ().getType ();
475
- }
476
-
477
- void MulElemOp::print (OpAsmPrinter &p) {
478
- printMulFMAElemOp<aievec::MulElemOp>(p, *this );
479
- }
480
-
481
- void aievec::FMAElemOp::print (OpAsmPrinter &p) {
482
- printMulFMAElemOp<aievec::FMAElemOp>(p, *this );
483
- }
484
-
485
- // Verify MulElem and FMAElem op.
486
- template <typename T>
487
- LogicalResult verifyMulFMAElemOp (T op) {
488
- // Verify the types
489
- auto lhsType = llvm::dyn_cast<VectorType>(op.getLhs ().getType ());
490
- auto rhsType = llvm::dyn_cast<VectorType>(op.getRhs ().getType ());
491
-
492
- if (!lhsType || !rhsType) return op.emitError (" requires vector type" );
493
-
494
- auto resultType = llvm::dyn_cast<VectorType>(op.getResult ().getType ());
495
-
496
- if (!resultType) return op.emitError (" requires vector type" );
497
-
498
- // Additional checks for FMAElem op
499
- // Get the width of the underlying scalars of all the vectors
500
- Type ltype = lhsType.getElementType ();
501
- Type rtype = rhsType.getElementType ();
502
- Type atype = resultType.getElementType ();
503
- unsigned ltypeWidth = ltype.getIntOrFloatBitWidth ();
504
- unsigned rtypeWidth = rtype.getIntOrFloatBitWidth ();
505
- unsigned atypeWidth = atype.getIntOrFloatBitWidth ();
506
-
507
- // Checks on the number of lanes
508
- unsigned rhsLanes = getVectorLaneSize (rhsType);
509
- unsigned lhsLanes = getVectorLaneSize (lhsType);
510
-
511
- // lane size must match
512
- if (lhsLanes != rhsLanes) {
513
- return op.emitError (
514
- " The number of lanes in lhs operand "
515
- " must be the same as rhs operand" );
516
- }
517
-
518
- // lhs and rhs vector's element type must match
519
- if (ltype != rtype)
520
- return op.emitError (
521
- " The element type of lhs and rhs "
522
- " operand vectors must match" );
523
-
524
- // The integer datatype of accumulator must always be greater width
525
- if (isa<IntegerType>(atype)) {
526
- if (!isa<IntegerType>(ltype))
527
- return op.emitError (" Integer result must have integer operands" );
528
-
529
- if (ltypeWidth >= atypeWidth || rtypeWidth >= atypeWidth)
530
- return op.emitError (
531
- " the element type of accumulator must have "
532
- " wider width than that of the operand vectors" );
533
- } else if (isa<FloatType>(atype)) {
534
- if (!isa<FloatType>(ltype))
535
- return op.emitError (
536
- " Floating point result must have "
537
- " floating point operands" );
538
- }
539
-
540
- return success ();
541
- }
542
-
543
- LogicalResult aievec::MulElemOp::verify () {
544
- return verifyMulFMAElemOp<aievec::MulElemOp>(*this );
545
- }
546
-
547
- LogicalResult aievec::FMAElemOp::verify () {
548
- return verifyMulFMAElemOp<aievec::FMAElemOp>(*this );
549
- }
550
-
551
- // Parse MulElem and FMAElem op.
552
- ParseResult parseMulFMAElemOp (OpAsmParser &parser, OperationState &result,
553
- bool isFMAElemOp = true ) {
554
- llvm::SMLoc typesLoc;
555
- SmallVector<Type, 3 > types;
556
- OpAsmParser::UnresolvedOperand lhs, rhs, acc;
557
-
558
- // Parse the lhs and rhs
559
- if (parser.parseOperand (lhs) || parser.parseComma () ||
560
- parser.parseOperand (rhs))
561
- return failure ();
562
-
563
- // Parse the acc for FMA op
564
- if (isFMAElemOp) {
565
- if (parser.parseComma () || parser.parseOperand (acc)) return failure ();
566
- }
567
-
568
- // Parse all the attributes and types
569
- if (parser.parseOptionalAttrDict (result.attributes ) ||
570
- parser.getCurrentLocation (&typesLoc) || parser.parseColonTypeList (types))
571
- return failure ();
572
-
573
- // Assert that there are three types: lhs, rhs, and acc
574
- if (types.size () != 3 )
575
- return parser.emitError (typesLoc, " requires three types" );
576
-
577
- // Some verification
578
- VectorType lhsType = llvm::dyn_cast<VectorType>(types[0 ]);
579
- if (!lhsType) return parser.emitError (typesLoc, " requires vector type" );
580
- VectorType rhsType = llvm::dyn_cast<VectorType>(types[1 ]);
581
- if (!rhsType) return parser.emitError (typesLoc, " requires vector type" );
582
-
583
- // Int ops use the accumulator while float ops use normal vector registers
584
- VectorType accType = llvm::dyn_cast<VectorType>(types[2 ]);
585
- if (!accType) return parser.emitError (typesLoc, " requires vector type" );
586
-
587
- // Populate the lhs and rhs operands, and result
588
- if (parser.resolveOperand (lhs, lhsType, result.operands ) ||
589
- parser.resolveOperand (rhs, rhsType, result.operands ))
590
- return failure ();
591
-
592
- // Populate acc operand for FMA op
593
- if (isFMAElemOp) {
594
- if (parser.resolveOperand (acc, accType, result.operands )) return failure ();
595
- }
596
-
597
- return parser.addTypeToList (accType, result.types );
598
- }
599
-
600
- ParseResult MulElemOp::parse (OpAsmParser &parser, OperationState &result) {
601
- return parseMulFMAElemOp (parser, result, false );
602
- }
603
-
604
- ParseResult FMAElemOp::parse (OpAsmParser &parser, OperationState &result) {
605
- return parseMulFMAElemOp (parser, result, true );
606
- }
607
-
608
423
// ===----------------------------------------------------------------------===//
609
424
// ExtOp
610
425
// ===----------------------------------------------------------------------===//
0 commit comments