forked from OSchip/llvm-project
[SDAG] add simplifications for FP at node creation time
We have the folds for fadd/fsub/fmul already in DAGCombiner, so it may be possible to remove that code if we can guarantee that these ops are zapped before they can exist. llvm-svn: 357029
This commit is contained in:
parent
e1d79a87c6
commit
bb5cba3cca
|
@ -976,6 +976,10 @@ public:
|
|||
/// Try to simplify a shift into 1 of its operands or a constant.
|
||||
SDValue simplifyShift(SDValue X, SDValue Y);
|
||||
|
||||
/// Try to simplify a floating-point binary operation into 1 of its operands
|
||||
/// or a constant.
|
||||
SDValue simplifyFPBinop(unsigned Opcode, SDValue X, SDValue Y);
|
||||
|
||||
/// VAArg produces a result and token chain, and takes a pointer
|
||||
/// and a source value as input.
|
||||
SDValue getVAArg(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
|
||||
|
|
|
@ -4931,6 +4931,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
|||
assert(VT.isFloatingPoint() && "This operator only applies to FP types!");
|
||||
assert(N1.getValueType() == N2.getValueType() &&
|
||||
N1.getValueType() == VT && "Binary operator types must match!");
|
||||
if (SDValue V = simplifyFPBinop(Opcode, N1, N2))
|
||||
return V;
|
||||
break;
|
||||
case ISD::FCOPYSIGN: // N1 and result must match. N1/N2 need not match.
|
||||
assert(N1.getValueType() == VT &&
|
||||
|
@ -7053,6 +7055,31 @@ SDValue SelectionDAG::simplifyShift(SDValue X, SDValue Y) {
|
|||
return SDValue();
|
||||
}
|
||||
|
||||
// TODO: Use fast-math-flags to enable more simplifications.
|
||||
SDValue SelectionDAG::simplifyFPBinop(unsigned Opcode, SDValue X, SDValue Y) {
|
||||
ConstantFPSDNode *YC = isConstOrConstSplatFP(Y, /* AllowUndefs */ true);
|
||||
if (!YC)
|
||||
return SDValue();
|
||||
|
||||
// X + -0.0 --> X
|
||||
if (Opcode == ISD::FADD)
|
||||
if (YC->getValueAPF().isNegZero())
|
||||
return X;
|
||||
|
||||
// X - +0.0 --> X
|
||||
if (Opcode == ISD::FSUB)
|
||||
if (YC->getValueAPF().isPosZero())
|
||||
return X;
|
||||
|
||||
// X * 1.0 --> X
|
||||
// X / 1.0 --> X
|
||||
if (Opcode == ISD::FMUL || Opcode == ISD::FDIV)
|
||||
if (YC->getValueAPF().isExactlyValue(1.0))
|
||||
return X;
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getVAArg(EVT VT, const SDLoc &dl, SDValue Chain,
|
||||
SDValue Ptr, SDValue SV, unsigned Align) {
|
||||
SDValue Ops[] = { Chain, Ptr, SV, getTargetConstant(Align, dl, MVT::i32) };
|
||||
|
|
|
@ -36,12 +36,11 @@ define float @ext_fmul_v4f32(<4 x float> %x) {
|
|||
ret float %ext
|
||||
}
|
||||
|
||||
; TODO: X / 1.0 --> X
|
||||
; X / 1.0 --> X
|
||||
|
||||
define float @ext_fdiv_v4f32(<4 x float> %x) {
|
||||
; CHECK-LABEL: ext_fdiv_v4f32:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: divss {{.*}}(%rip), %xmm0
|
||||
; CHECK-NEXT: retq
|
||||
%bo = fdiv <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 42.0>
|
||||
%ext = extractelement <4 x float> %bo, i32 0
|
||||
|
|
Loading…
Reference in New Issue