|
@@ -671,13 +671,9 @@ bool llvm::hasIterationCountInvariantInParent(Loop *InnerLoop,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-/// Adds a 'fast' flag to floating point operations.
|
|
|
-static Value *addFastMathFlag(Value *V) {
|
|
|
- if (isa<FPMathOperator>(V)) {
|
|
|
- FastMathFlags Flags;
|
|
|
- Flags.setFast();
|
|
|
- cast<Instruction>(V)->setFastMathFlags(Flags);
|
|
|
- }
|
|
|
+static Value *addFastMathFlag(Value *V, FastMathFlags FMF) {
|
|
|
+ if (isa<FPMathOperator>(V))
|
|
|
+ cast<Instruction>(V)->setFastMathFlags(FMF);
|
|
|
return V;
|
|
|
}
|
|
|
|
|
@@ -761,7 +757,7 @@ llvm::getOrderedReduction(IRBuilder<> &Builder, Value *Acc, Value *Src,
|
|
|
Value *
|
|
|
llvm::getShuffleReduction(IRBuilder<> &Builder, Value *Src, unsigned Op,
|
|
|
RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind,
|
|
|
- ArrayRef<Value *> RedOps) {
|
|
|
+ FastMathFlags FMF, ArrayRef<Value *> RedOps) {
|
|
|
unsigned VF = Src->getType()->getVectorNumElements();
|
|
|
// VF is a power of 2 so we can emit the reduction using log2(VF) shuffles
|
|
|
// and vector ops, reducing the set of values being computed by half each
|
|
@@ -786,7 +782,8 @@ llvm::getShuffleReduction(IRBuilder<> &Builder, Value *Src, unsigned Op,
|
|
|
if (Op != Instruction::ICmp && Op != Instruction::FCmp) {
|
|
|
// Floating point operations had to be 'fast' to enable the reduction.
|
|
|
TmpVec = addFastMathFlag(Builder.CreateBinOp((Instruction::BinaryOps)Op,
|
|
|
- TmpVec, Shuf, "bin.rdx"));
|
|
|
+ TmpVec, Shuf, "bin.rdx"),
|
|
|
+ FMF);
|
|
|
} else {
|
|
|
assert(MinMaxKind != RecurrenceDescriptor::MRK_Invalid &&
|
|
|
"Invalid min/max");
|
|
@@ -803,7 +800,7 @@ llvm::getShuffleReduction(IRBuilder<> &Builder, Value *Src, unsigned Op,
|
|
|
/// flags (if generating min/max reductions).
|
|
|
Value *llvm::createSimpleTargetReduction(
|
|
|
IRBuilder<> &Builder, const TargetTransformInfo *TTI, unsigned Opcode,
|
|
|
- Value *Src, TargetTransformInfo::ReductionFlags Flags,
|
|
|
+ Value *Src, TargetTransformInfo::ReductionFlags Flags, FastMathFlags FMF,
|
|
|
ArrayRef<Value *> RedOps) {
|
|
|
assert(isa<VectorType>(Src->getType()) && "Type must be a vector");
|
|
|
|
|
@@ -873,7 +870,7 @@ Value *llvm::createSimpleTargetReduction(
|
|
|
}
|
|
|
if (TTI->useReductionIntrinsic(Opcode, Src->getType(), Flags))
|
|
|
return BuildFunc();
|
|
|
- return getShuffleReduction(Builder, Src, Opcode, MinMaxKind, RedOps);
|
|
|
+ return getShuffleReduction(Builder, Src, Opcode, MinMaxKind, FMF, RedOps);
|
|
|
}
|
|
|
|
|
|
/// Create a vector reduction using a given recurrence descriptor.
|
|
@@ -888,28 +885,37 @@ Value *llvm::createTargetReduction(IRBuilder<> &B,
|
|
|
Flags.NoNaN = NoNaN;
|
|
|
switch (RecKind) {
|
|
|
case RD::RK_FloatAdd:
|
|
|
- return createSimpleTargetReduction(B, TTI, Instruction::FAdd, Src, Flags);
|
|
|
+ return createSimpleTargetReduction(B, TTI, Instruction::FAdd, Src, Flags,
|
|
|
+ Desc.getFastMathFlags());
|
|
|
case RD::RK_FloatMult:
|
|
|
- return createSimpleTargetReduction(B, TTI, Instruction::FMul, Src, Flags);
|
|
|
+ return createSimpleTargetReduction(B, TTI, Instruction::FMul, Src, Flags,
|
|
|
+ Desc.getFastMathFlags());
|
|
|
case RD::RK_IntegerAdd:
|
|
|
- return createSimpleTargetReduction(B, TTI, Instruction::Add, Src, Flags);
|
|
|
+ return createSimpleTargetReduction(B, TTI, Instruction::Add, Src, Flags,
|
|
|
+ Desc.getFastMathFlags());
|
|
|
case RD::RK_IntegerMult:
|
|
|
- return createSimpleTargetReduction(B, TTI, Instruction::Mul, Src, Flags);
|
|
|
+ return createSimpleTargetReduction(B, TTI, Instruction::Mul, Src, Flags,
|
|
|
+ Desc.getFastMathFlags());
|
|
|
case RD::RK_IntegerAnd:
|
|
|
- return createSimpleTargetReduction(B, TTI, Instruction::And, Src, Flags);
|
|
|
+ return createSimpleTargetReduction(B, TTI, Instruction::And, Src, Flags,
|
|
|
+ Desc.getFastMathFlags());
|
|
|
case RD::RK_IntegerOr:
|
|
|
- return createSimpleTargetReduction(B, TTI, Instruction::Or, Src, Flags);
|
|
|
+ return createSimpleTargetReduction(B, TTI, Instruction::Or, Src, Flags,
|
|
|
+ Desc.getFastMathFlags());
|
|
|
case RD::RK_IntegerXor:
|
|
|
- return createSimpleTargetReduction(B, TTI, Instruction::Xor, Src, Flags);
|
|
|
+ return createSimpleTargetReduction(B, TTI, Instruction::Xor, Src, Flags,
|
|
|
+ Desc.getFastMathFlags());
|
|
|
case RD::RK_IntegerMinMax: {
|
|
|
RD::MinMaxRecurrenceKind MMKind = Desc.getMinMaxRecurrenceKind();
|
|
|
Flags.IsMaxOp = (MMKind == RD::MRK_SIntMax || MMKind == RD::MRK_UIntMax);
|
|
|
Flags.IsSigned = (MMKind == RD::MRK_SIntMax || MMKind == RD::MRK_SIntMin);
|
|
|
- return createSimpleTargetReduction(B, TTI, Instruction::ICmp, Src, Flags);
|
|
|
+ return createSimpleTargetReduction(B, TTI, Instruction::ICmp, Src, Flags,
|
|
|
+ Desc.getFastMathFlags());
|
|
|
}
|
|
|
case RD::RK_FloatMinMax: {
|
|
|
Flags.IsMaxOp = Desc.getMinMaxRecurrenceKind() == RD::MRK_FloatMax;
|
|
|
- return createSimpleTargetReduction(B, TTI, Instruction::FCmp, Src, Flags);
|
|
|
+ return createSimpleTargetReduction(B, TTI, Instruction::FCmp, Src, Flags,
|
|
|
+ Desc.getFastMathFlags());
|
|
|
}
|
|
|
default:
|
|
|
llvm_unreachable("Unhandled RecKind");
|