@@ -1140,6 +1140,80 @@ void VPWidenRecipe::execute(VPTransformState &State) {
1140
1140
#endif
1141
1141
}
1142
1142
1143
+ InstructionCost VPWidenRecipe::computeCost (ElementCount VF,
1144
+ VPCostContext &Ctx) const {
1145
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
1146
+ switch (Opcode) {
1147
+ case Instruction::FNeg: {
1148
+ Type *VectorTy =
1149
+ ToVectorTy (Ctx.Types .inferScalarType (this ->getVPSingleValue ()), VF);
1150
+ return Ctx.TTI .getArithmeticInstrCost (
1151
+ Opcode, VectorTy, CostKind,
1152
+ {TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None},
1153
+ {TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None});
1154
+ }
1155
+
1156
+ case Instruction::UDiv:
1157
+ case Instruction::SDiv:
1158
+ case Instruction::SRem:
1159
+ case Instruction::URem:
1160
+ // More complex computation, let the legacy cost-model handle this for now.
1161
+ return Ctx.getLegacyCost (cast<Instruction>(getUnderlyingValue ()), VF);
1162
+ case Instruction::Add:
1163
+ case Instruction::FAdd:
1164
+ case Instruction::Sub:
1165
+ case Instruction::FSub:
1166
+ case Instruction::Mul:
1167
+ case Instruction::FMul:
1168
+ case Instruction::FDiv:
1169
+ case Instruction::FRem:
1170
+ case Instruction::Shl:
1171
+ case Instruction::LShr:
1172
+ case Instruction::AShr:
1173
+ case Instruction::And:
1174
+ case Instruction::Or:
1175
+ case Instruction::Xor: {
1176
+ VPValue *RHS = getOperand (1 );
1177
+ // Certain instructions can be cheaper to vectorize if they have a constant
1178
+ // second vector operand. One example of this are shifts on x86.
1179
+ TargetTransformInfo::OperandValueInfo RHSInfo = {
1180
+ TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None};
1181
+ if (RHS->isLiveIn ())
1182
+ RHSInfo = Ctx.TTI .getOperandInfo (RHS->getLiveInIRValue ());
1183
+
1184
+ if (RHSInfo.Kind == TargetTransformInfo::OK_AnyValue &&
1185
+ getOperand (1 )->isDefinedOutsideVectorRegions ())
1186
+ RHSInfo.Kind = TargetTransformInfo::OK_UniformValue;
1187
+ Type *VectorTy =
1188
+ ToVectorTy (Ctx.Types .inferScalarType (this ->getVPSingleValue ()), VF);
1189
+ Instruction *CtxI = dyn_cast_or_null<Instruction>(getUnderlyingValue ());
1190
+
1191
+ SmallVector<const Value *, 4 > Operands;
1192
+ if (CtxI)
1193
+ Operands.append (CtxI->value_op_begin (), CtxI->value_op_end ());
1194
+ return Ctx.TTI .getArithmeticInstrCost (
1195
+ Opcode, VectorTy, CostKind,
1196
+ {TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None},
1197
+ RHSInfo, Operands, CtxI, &Ctx.TLI );
1198
+ }
1199
+ case Instruction::Freeze: {
1200
+ // This opcode is unknown. Assume that it is the same as 'mul'.
1201
+ Type *VectorTy =
1202
+ ToVectorTy (Ctx.Types .inferScalarType (this ->getVPSingleValue ()), VF);
1203
+ return Ctx.TTI .getArithmeticInstrCost (Instruction::Mul, VectorTy, CostKind);
1204
+ }
1205
+ case Instruction::ICmp:
1206
+ case Instruction::FCmp: {
1207
+ Instruction *CtxI = dyn_cast_or_null<Instruction>(getUnderlyingValue ());
1208
+ Type *VectorTy = ToVectorTy (Ctx.Types .inferScalarType (getOperand (0 )), VF);
1209
+ return Ctx.TTI .getCmpSelInstrCost (Opcode, VectorTy, nullptr , getPredicate (),
1210
+ CostKind, CtxI);
1211
+ }
1212
+ default :
1213
+ llvm_unreachable (" Unsupported opcode for instruction" );
1214
+ }
1215
+ }
1216
+
1143
1217
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1144
1218
void VPWidenRecipe::print (raw_ostream &O, const Twine &Indent,
1145
1219
VPSlotTracker &SlotTracker) const {
0 commit comments