@@ -414,6 +414,20 @@ CallInst *IRBuilderBase::getReductionIntrinsic(Intrinsic::ID ID, Value *Src) {
414
414
return CreateCall (Decl, Ops);
415
415
}
416
416
417
+ CallInst *IRBuilderBase::getReductionIntrinsic (Intrinsic::ID ID, Value *Acc,
418
+ Value *Src, Value *Mask,
419
+ Value *EVL) {
420
+ Module *M = GetInsertBlock ()->getParent ()->getParent ();
421
+ auto *SrcTy = cast<VectorType>(Src->getType ());
422
+ EVL = CreateIntCast (EVL, getInt32Ty (), /* isSigned=*/ false );
423
+ if (!Mask)
424
+ Mask = CreateVectorSplat (SrcTy->getElementCount (), getTrue ());
425
+ Value *Ops[] = {Acc, Src, Mask, EVL};
426
+ Type *Tys[] = {SrcTy};
427
+ auto Decl = Intrinsic::getDeclaration (M, ID, Tys);
428
+ return CreateCall (Decl, Ops);
429
+ }
430
+
417
431
CallInst *IRBuilderBase::CreateFAddReduce (Value *Acc, Value *Src) {
418
432
Module *M = GetInsertBlock ()->getParent ()->getParent ();
419
433
Value *Ops[] = {Acc, Src};
@@ -422,6 +436,11 @@ CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) {
422
436
return CreateCall (Decl, Ops);
423
437
}
424
438
439
+ CallInst *IRBuilderBase::CreateFAddReduce (Value *Acc, Value *Src, Value *EVL,
440
+ Value *Mask) {
441
+ return getReductionIntrinsic (Intrinsic::vp_reduce_fadd, Acc, Src, Mask, EVL);
442
+ }
443
+
425
444
CallInst *IRBuilderBase::CreateFMulReduce (Value *Acc, Value *Src) {
426
445
Module *M = GetInsertBlock ()->getParent ()->getParent ();
427
446
Value *Ops[] = {Acc, Src};
@@ -430,46 +449,149 @@ CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) {
430
449
return CreateCall (Decl, Ops);
431
450
}
432
451
452
+ CallInst *IRBuilderBase::CreateFMulReduce (Value *Acc, Value *Src, Value *EVL,
453
+ Value *Mask) {
454
+ return getReductionIntrinsic (Intrinsic::vp_reduce_fmul, Acc, Src, Mask, EVL);
455
+ }
456
+
433
457
CallInst *IRBuilderBase::CreateAddReduce (Value *Src) {
434
458
return getReductionIntrinsic (Intrinsic::vector_reduce_add, Src);
435
459
}
436
460
461
+ CallInst *IRBuilderBase::CreateAddReduce (Value *Src, Value *EVL, Value *Mask) {
462
+ auto *SrcTy = cast<VectorType>(Src->getType ());
463
+ auto *EltTy = SrcTy->getElementType ();
464
+ return getReductionIntrinsic (Intrinsic::vp_reduce_add,
465
+ ConstantInt::get (EltTy, 0 ), Src, Mask, EVL);
466
+ }
467
+
437
468
CallInst *IRBuilderBase::CreateMulReduce (Value *Src) {
438
469
return getReductionIntrinsic (Intrinsic::vector_reduce_mul, Src);
439
470
}
440
471
472
+ CallInst *IRBuilderBase::CreateMulReduce (Value *Src, Value *EVL, Value *Mask) {
473
+ auto *SrcTy = cast<VectorType>(Src->getType ());
474
+ auto *EltTy = SrcTy->getElementType ();
475
+ return getReductionIntrinsic (Intrinsic::vp_reduce_mul,
476
+ ConstantInt::get (EltTy, 1 ), Src, Mask, EVL);
477
+ }
478
+
441
479
CallInst *IRBuilderBase::CreateAndReduce (Value *Src) {
442
480
return getReductionIntrinsic (Intrinsic::vector_reduce_and, Src);
443
481
}
444
482
483
+ CallInst *IRBuilderBase::CreateAndReduce (Value *Src, Value *EVL, Value *Mask) {
484
+ auto *SrcTy = cast<VectorType>(Src->getType ());
485
+ auto *EltTy = SrcTy->getElementType ();
486
+ return getReductionIntrinsic (Intrinsic::vp_reduce_and,
487
+ Constant::getAllOnesValue (EltTy), Src, Mask,
488
+ EVL);
489
+ }
490
+
445
491
CallInst *IRBuilderBase::CreateOrReduce (Value *Src) {
446
492
return getReductionIntrinsic (Intrinsic::vector_reduce_or, Src);
447
493
}
448
494
495
+ CallInst *IRBuilderBase::CreateOrReduce (Value *Src, Value *EVL, Value *Mask) {
496
+ auto *SrcTy = cast<VectorType>(Src->getType ());
497
+ auto *EltTy = SrcTy->getElementType ();
498
+ return getReductionIntrinsic (Intrinsic::vp_reduce_or,
499
+ ConstantInt::get (EltTy, 0 ), Src, Mask, EVL);
500
+ }
501
+
449
502
CallInst *IRBuilderBase::CreateXorReduce (Value *Src) {
450
503
return getReductionIntrinsic (Intrinsic::vector_reduce_xor, Src);
451
504
}
452
505
506
+ CallInst *IRBuilderBase::CreateXorReduce (Value *Src, Value *EVL, Value *Mask) {
507
+ auto *SrcTy = cast<VectorType>(Src->getType ());
508
+ auto *EltTy = SrcTy->getElementType ();
509
+ return getReductionIntrinsic (Intrinsic::vp_reduce_xor,
510
+ ConstantInt::get (EltTy, 0 ), Src, Mask, EVL);
511
+ }
512
+
453
513
CallInst *IRBuilderBase::CreateIntMaxReduce (Value *Src, bool IsSigned) {
454
514
auto ID =
455
515
IsSigned ? Intrinsic::vector_reduce_smax : Intrinsic::vector_reduce_umax;
456
516
return getReductionIntrinsic (ID, Src);
457
517
}
458
518
519
+ CallInst *IRBuilderBase::CreateIntMaxReduce (Value *Src, Value *EVL,
520
+ bool IsSigned, Value *Mask) {
521
+ auto *SrcTy = cast<VectorType>(Src->getType ());
522
+ auto *EltTy = SrcTy->getElementType ();
523
+ return getReductionIntrinsic (
524
+ IsSigned ? Intrinsic::vp_reduce_smax : Intrinsic::vp_reduce_umax,
525
+ IsSigned ? ConstantInt::get (EltTy, APInt::getSignedMinValue (
526
+ EltTy->getIntegerBitWidth ()))
527
+ : ConstantInt::get (EltTy, 0 ),
528
+ Src, Mask, EVL);
529
+ }
530
+
459
531
CallInst *IRBuilderBase::CreateIntMinReduce (Value *Src, bool IsSigned) {
460
532
auto ID =
461
533
IsSigned ? Intrinsic::vector_reduce_smin : Intrinsic::vector_reduce_umin;
462
534
return getReductionIntrinsic (ID, Src);
463
535
}
464
536
537
+ CallInst *IRBuilderBase::CreateIntMinReduce (Value *Src, Value *EVL,
538
+ bool IsSigned, Value *Mask) {
539
+ auto *SrcTy = cast<VectorType>(Src->getType ());
540
+ auto *EltTy = SrcTy->getElementType ();
541
+ return getReductionIntrinsic (
542
+ IsSigned ? Intrinsic::vp_reduce_smin : Intrinsic::vp_reduce_umin,
543
+ IsSigned ? ConstantInt::get (EltTy, APInt::getSignedMaxValue (
544
+ EltTy->getIntegerBitWidth ()))
545
+ : Constant::getAllOnesValue (EltTy),
546
+ Src, Mask, EVL);
547
+ }
548
+
465
549
CallInst *IRBuilderBase::CreateFPMaxReduce (Value *Src) {
466
550
return getReductionIntrinsic (Intrinsic::vector_reduce_fmax, Src);
467
551
}
468
552
553
+ CallInst *IRBuilderBase::CreateFPMaxReduce (Value *Src, Value *EVL,
554
+ Value *Mask) {
555
+ auto *SrcTy = cast<VectorType>(Src->getType ());
556
+ auto *EltTy = SrcTy->getElementType ();
557
+ FastMathFlags FMF = getFastMathFlags ();
558
+ Value *Neutral;
559
+ if (FMF.noNaNs ())
560
+ Neutral = FMF.noInfs ()
561
+ ? ConstantFP::get (
562
+ EltTy, APFloat::getLargest (EltTy->getFltSemantics (),
563
+ /* Negative=*/ true ))
564
+ : ConstantFP::getInfinity (EltTy, true );
565
+ else
566
+ Neutral = ConstantFP::getQNaN (EltTy, /* Negative=*/ true );
567
+
568
+ return getReductionIntrinsic (Intrinsic::vp_reduce_fmax, Neutral, Src, Mask,
569
+ EVL);
570
+ }
571
+
469
572
CallInst *IRBuilderBase::CreateFPMinReduce (Value *Src) {
470
573
return getReductionIntrinsic (Intrinsic::vector_reduce_fmin, Src);
471
574
}
472
575
576
+ CallInst *IRBuilderBase::CreateFPMinReduce (Value *Src, Value *EVL,
577
+ Value *Mask) {
578
+ auto *SrcTy = cast<VectorType>(Src->getType ());
579
+ auto *EltTy = SrcTy->getElementType ();
580
+ FastMathFlags FMF = getFastMathFlags ();
581
+ Value *Neutral;
582
+ if (FMF.noNaNs ())
583
+ Neutral = FMF.noInfs ()
584
+ ? ConstantFP::get (
585
+ EltTy, APFloat::getLargest (EltTy->getFltSemantics (),
586
+ /* Negative=*/ false ))
587
+ : ConstantFP::getInfinity (EltTy, false );
588
+ else
589
+ Neutral = ConstantFP::getQNaN (EltTy, /* Negative=*/ false );
590
+
591
+ return getReductionIntrinsic (Intrinsic::vp_reduce_fmin, Neutral, Src, Mask,
592
+ EVL);
593
+ }
594
+
473
595
CallInst *IRBuilderBase::CreateFPMaximumReduce (Value *Src) {
474
596
return getReductionIntrinsic (Intrinsic::vector_reduce_fmaximum, Src);
475
597
}
0 commit comments