From bb5cba3cca070e0a7eb85ef25c513cd6b86ddd01 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 26 Mar 2019 20:54:15 +0000 Subject: [PATCH] [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 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 4 ++++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 27 ++++++++++++++++++++++++++ llvm/test/CodeGen/X86/extract-fp.ll | 3 +-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 548c28f..aac3e0f 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -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, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index e9ef415..9534704 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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) }; diff --git a/llvm/test/CodeGen/X86/extract-fp.ll b/llvm/test/CodeGen/X86/extract-fp.ll index 06ba30b..5632450 100644 --- a/llvm/test/CodeGen/X86/extract-fp.ll +++ b/llvm/test/CodeGen/X86/extract-fp.ll @@ -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, %ext = extractelement <4 x float> %bo, i32 0 -- 2.7.4