@@ -67,10 +67,43 @@ static bool isIntrinsicExpansion(Function &F) {
6767 case Intrinsic::dx_sign:
6868 case Intrinsic::dx_step:
6969 case Intrinsic::dx_radians:
70+ case Intrinsic::vector_reduce_add:
71+ case Intrinsic::vector_reduce_fadd:
7072 return true ;
7173 }
7274 return false ;
7375}
76+ static Value *expandVecReduceAdd (CallInst *Orig, Intrinsic::ID IntrinsicId) {
77+ assert (IntrinsicId == Intrinsic::vector_reduce_add ||
78+ IntrinsicId == Intrinsic::vector_reduce_fadd);
79+
80+ IRBuilder<> Builder (Orig);
81+ bool IsFAdd = (IntrinsicId == Intrinsic::vector_reduce_fadd);
82+
83+ Value *X = Orig->getOperand (IsFAdd ? 1 : 0 );
84+ Type *Ty = X->getType ();
85+ auto *XVec = dyn_cast<FixedVectorType>(Ty);
86+ unsigned XVecSize = XVec->getNumElements ();
87+ Value *Sum = Builder.CreateExtractElement (X, static_cast <uint64_t >(0 ));
88+
89+ // Handle the initial start value for floating-point addition.
90+ if (IsFAdd) {
91+ Constant *StartValue = dyn_cast<Constant>(Orig->getOperand (0 ));
92+ if (StartValue && !StartValue->isZeroValue ())
93+ Sum = Builder.CreateFAdd (Sum, StartValue);
94+ }
95+
96+ // Accumulate the remaining vector elements.
97+ for (unsigned I = 1 ; I < XVecSize; I++) {
98+ Value *Elt = Builder.CreateExtractElement (X, I);
99+ if (IsFAdd)
100+ Sum = Builder.CreateFAdd (Sum, Elt);
101+ else
102+ Sum = Builder.CreateAdd (Sum, Elt);
103+ }
104+
105+ return Sum;
106+ }
74107
75108static Value *expandAbs (CallInst *Orig) {
76109 Value *X = Orig->getOperand (0 );
@@ -580,6 +613,10 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
580613 case Intrinsic::dx_radians:
581614 Result = expandRadiansIntrinsic (Orig);
582615 break ;
616+ case Intrinsic::vector_reduce_add:
617+ case Intrinsic::vector_reduce_fadd:
618+ Result = expandVecReduceAdd (Orig, IntrinsicId);
619+ break ;
583620 }
584621 if (Result) {
585622 Orig->replaceAllUsesWith (Result);
0 commit comments