return In;
}
-static Constant *simplifyFPBinop(Value *Op0, Value *Op1) {
- if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
- return ConstantFP::getNaN(Op0->getType());
+/// Perform folds that are common to any floating-point operation. This implies
+/// transforms based on undef/NaN because the operation itself makes no
+/// difference to the result.
+static Constant *simplifyFPOp(ArrayRef<Value *> Ops) {
+ if (any_of(Ops, [](Value *V) { return isa<UndefValue>(V); }))
+ return ConstantFP::getNaN(Ops[0]->getType());
- if (match(Op0, m_NaN()))
- return propagateNaN(cast<Constant>(Op0));
- if (match(Op1, m_NaN()))
- return propagateNaN(cast<Constant>(Op1));
+ for (Value *V : Ops)
+ if (match(V, m_NaN()))
+ return propagateNaN(cast<Constant>(V));
return nullptr;
}
if (Constant *C = foldOrCommuteConstant(Instruction::FAdd, Op0, Op1, Q))
return C;
- if (Constant *C = simplifyFPBinop(Op0, Op1))
+ if (Constant *C = simplifyFPOp({Op0, Op1}))
return C;
// fadd X, -0 ==> X
if (Constant *C = foldOrCommuteConstant(Instruction::FSub, Op0, Op1, Q))
return C;
- if (Constant *C = simplifyFPBinop(Op0, Op1))
+ if (Constant *C = simplifyFPOp({Op0, Op1}))
return C;
// fsub X, +0 ==> X
if (Constant *C = foldOrCommuteConstant(Instruction::FMul, Op0, Op1, Q))
return C;
- if (Constant *C = simplifyFPBinop(Op0, Op1))
+ if (Constant *C = simplifyFPOp({Op0, Op1}))
return C;
// Now apply simplifications that do not require rounding.
if (Constant *C = foldOrCommuteConstant(Instruction::FDiv, Op0, Op1, Q))
return C;
- if (Constant *C = simplifyFPBinop(Op0, Op1))
+ if (Constant *C = simplifyFPOp({Op0, Op1}))
return C;
// X / 1.0 -> X
if (Constant *C = foldOrCommuteConstant(Instruction::FRem, Op0, Op1, Q))
return C;
- if (Constant *C = simplifyFPBinop(Op0, Op1))
+ if (Constant *C = simplifyFPOp({Op0, Op1}))
return C;
// Unlike fdiv, the result of frem always matches the sign of the dividend.