@@ -4023,6 +4023,122 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
4023
4023
transValue (II->getArgOperand (0 ), BB),
4024
4024
transValue (II->getArgOperand (1 ), BB), BB);
4025
4025
}
4026
+ case Intrinsic::vector_reduce_add:
4027
+ case Intrinsic::vector_reduce_mul:
4028
+ case Intrinsic::vector_reduce_and:
4029
+ case Intrinsic::vector_reduce_or:
4030
+ case Intrinsic::vector_reduce_xor: {
4031
+ Op Op;
4032
+ if (IID == Intrinsic::vector_reduce_add) {
4033
+ Op = OpIAdd;
4034
+ } else if (IID == Intrinsic::vector_reduce_mul) {
4035
+ Op = OpIMul;
4036
+ } else if (IID == Intrinsic::vector_reduce_and) {
4037
+ Op = OpBitwiseAnd;
4038
+ } else if (IID == Intrinsic::vector_reduce_or) {
4039
+ Op = OpBitwiseOr;
4040
+ } else {
4041
+ Op = OpBitwiseXor;
4042
+ }
4043
+ VectorType *VecTy = cast<VectorType>(II->getArgOperand (0 )->getType ());
4044
+ SPIRVValue *VecSVal = transValue (II->getArgOperand (0 ), BB);
4045
+ SPIRVTypeInt *ResultSType =
4046
+ BM->addIntegerType (VecTy->getElementType ()->getIntegerBitWidth ());
4047
+ SPIRVTypeInt *I32STy = BM->addIntegerType (32 );
4048
+ unsigned VecSize = VecTy->getElementCount ().getFixedValue ();
4049
+ SmallVector<SPIRVValue *, 16 > Extracts (VecSize);
4050
+ for (unsigned Idx = 0 ; Idx < VecSize; ++Idx) {
4051
+ Extracts[Idx] = BM->addVectorExtractDynamicInst (
4052
+ VecSVal, BM->addIntegerConstant (I32STy, Idx), BB);
4053
+ }
4054
+ unsigned Counter = VecSize >> 1 ;
4055
+ while (Counter != 0 ) {
4056
+ for (unsigned Idx = 0 ; Idx < Counter; ++Idx) {
4057
+ Extracts[Idx] = BM->addBinaryInst (Op, ResultSType, Extracts[Idx << 1 ],
4058
+ Extracts[(Idx << 1 ) + 1 ], BB);
4059
+ }
4060
+ Counter >>= 1 ;
4061
+ }
4062
+ if ((VecSize & 1 ) != 0 ) {
4063
+ Extracts[0 ] = BM->addBinaryInst (Op, ResultSType, Extracts[0 ],
4064
+ Extracts[VecSize - 1 ], BB);
4065
+ }
4066
+ return Extracts[0 ];
4067
+ }
4068
+ case Intrinsic::vector_reduce_fadd:
4069
+ case Intrinsic::vector_reduce_fmul: {
4070
+ Op Op = IID == Intrinsic::vector_reduce_fadd ? OpFAdd : OpFMul;
4071
+ VectorType *VecTy = cast<VectorType>(II->getArgOperand (1 )->getType ());
4072
+ SPIRVValue *VecSVal = transValue (II->getArgOperand (1 ), BB);
4073
+ SPIRVValue *StartingSVal = transValue (II->getArgOperand (0 ), BB);
4074
+ SPIRVTypeInt *I32STy = BM->addIntegerType (32 );
4075
+ unsigned VecSize = VecTy->getElementCount ().getFixedValue ();
4076
+ SmallVector<SPIRVValue *, 16 > Extracts (VecSize);
4077
+ for (unsigned Idx = 0 ; Idx < VecSize; ++Idx) {
4078
+ Extracts[Idx] = BM->addVectorExtractDynamicInst (
4079
+ VecSVal, BM->addIntegerConstant (I32STy, Idx), BB);
4080
+ }
4081
+ SPIRVValue *V = BM->addBinaryInst (Op, StartingSVal->getType (), StartingSVal,
4082
+ Extracts[0 ], BB);
4083
+ for (unsigned Idx = 1 ; Idx < VecSize; ++Idx) {
4084
+ V = BM->addBinaryInst (Op, StartingSVal->getType (), V, Extracts[Idx], BB);
4085
+ }
4086
+ return V;
4087
+ }
4088
+ case Intrinsic::vector_reduce_smax:
4089
+ case Intrinsic::vector_reduce_smin:
4090
+ case Intrinsic::vector_reduce_umax:
4091
+ case Intrinsic::vector_reduce_umin:
4092
+ case Intrinsic::vector_reduce_fmax:
4093
+ case Intrinsic::vector_reduce_fmin:
4094
+ case Intrinsic::vector_reduce_fmaximum:
4095
+ case Intrinsic::vector_reduce_fminimum: {
4096
+ Op Op;
4097
+ if (IID == Intrinsic::vector_reduce_smax) {
4098
+ Op = OpSGreaterThan;
4099
+ } else if (IID == Intrinsic::vector_reduce_smin) {
4100
+ Op = OpSLessThan;
4101
+ } else if (IID == Intrinsic::vector_reduce_umax) {
4102
+ Op = OpUGreaterThan;
4103
+ } else if (IID == Intrinsic::vector_reduce_umin) {
4104
+ Op = OpULessThan;
4105
+ } else if (IID == Intrinsic::vector_reduce_fmax) {
4106
+ Op = OpFOrdGreaterThan;
4107
+ } else if (IID == Intrinsic::vector_reduce_fmin) {
4108
+ Op = OpFOrdLessThan;
4109
+ } else if (IID == Intrinsic::vector_reduce_fmaximum) {
4110
+ Op = OpFUnordGreaterThan;
4111
+ } else {
4112
+ Op = OpFUnordLessThan;
4113
+ }
4114
+ VectorType *VecTy = cast<VectorType>(II->getArgOperand (0 )->getType ());
4115
+ SPIRVValue *VecSVal = transValue (II->getArgOperand (0 ), BB);
4116
+ SPIRVType *BoolSTy = transType (Type::getInt1Ty (II->getContext ()));
4117
+ SPIRVTypeInt *I32STy = BM->addIntegerType (32 );
4118
+ unsigned VecSize = VecTy->getElementCount ().getFixedValue ();
4119
+ SmallVector<SPIRVValue *, 16 > Extracts (VecSize);
4120
+ for (unsigned Idx = 0 ; Idx < VecSize; ++Idx) {
4121
+ Extracts[Idx] = BM->addVectorExtractDynamicInst (
4122
+ VecSVal, BM->addIntegerConstant (I32STy, Idx), BB);
4123
+ }
4124
+ unsigned Counter = VecSize >> 1 ;
4125
+ while (Counter != 0 ) {
4126
+ for (unsigned Idx = 0 ; Idx < Counter; ++Idx) {
4127
+ SPIRVValue *Cond = BM->addBinaryInst (Op, BoolSTy, Extracts[Idx << 1 ],
4128
+ Extracts[(Idx << 1 ) + 1 ], BB);
4129
+ Extracts[Idx] = BM->addSelectInst (Cond, Extracts[Idx << 1 ],
4130
+ Extracts[(Idx << 1 ) + 1 ], BB);
4131
+ }
4132
+ Counter >>= 1 ;
4133
+ }
4134
+ if ((VecSize & 1 ) != 0 ) {
4135
+ SPIRVValue *Cond = BM->addBinaryInst (Op, BoolSTy, Extracts[0 ],
4136
+ Extracts[VecSize - 1 ], BB);
4137
+ Extracts[0 ] =
4138
+ BM->addSelectInst (Cond, Extracts[0 ], Extracts[VecSize - 1 ], BB);
4139
+ }
4140
+ return Extracts[0 ];
4141
+ }
4026
4142
case Intrinsic::memset: {
4027
4143
// Generally there is no direct mapping of memset to SPIR-V. But it turns
4028
4144
// out that memset is emitted by Clang for initialization in default
0 commit comments