[llvm] r360053 - Add FNeg support to InstructionSimplify

Cameron McInally via llvm-commits llvm-commits at lists.llvm.org
Mon May 6 09:05:10 PDT 2019


Author: mcinally
Date: Mon May  6 09:05:10 2019
New Revision: 360053

URL: http://llvm.org/viewvc/llvm-project?rev=360053&view=rev
Log:
Add FNeg support to InstructionSimplify

Differential Revision: https://reviews.llvm.org/D61573

Modified:
    llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
    llvm/trunk/test/Analysis/ConstantFolding/fneg.ll
    llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll

Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=360053&r1=360052&r2=360053&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original)
+++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Mon May  6 09:05:10 2019
@@ -117,6 +117,10 @@ struct SimplifyQuery {
 // deprecated.
 // Please use the SimplifyQuery versions in new code.
 
+/// Given operand for an FNeg, fold the result or return null.
+Value *SimplifyFNegInst(Value *Op, FastMathFlags FMF,
+                        const SimplifyQuery &Q);
+
 /// Given operands for an Add, fold the result or return null.
 Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
                        const SimplifyQuery &Q);
@@ -227,6 +231,15 @@ Value *SimplifyShuffleVectorInst(Value *
 Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
                        const SimplifyQuery &Q);
 
+/// Given operand for a UnaryOperator, fold the result or return null.
+Value *SimplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q);
+
+/// Given operand for an FP UnaryOperator, fold the result or return null.
+/// In contrast to SimplifyUnOp, try to use FastMathFlag when folding the
+/// result. In case we don't need FastMathFlags, simply fall to SimplifyUnOp.
+Value *SimplifyFPUnOp(unsigned Opcode, Value *Op, FastMathFlags FMF,
+                      const SimplifyQuery &Q);
+
 /// Given operands for a BinaryOperator, fold the result or return null.
 Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
                      const SimplifyQuery &Q);

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=360053&r1=360052&r2=360053&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon May  6 09:05:10 2019
@@ -51,6 +51,9 @@ STATISTIC(NumExpand,  "Number of expansi
 STATISTIC(NumReassoc, "Number of reassociations");
 
 static Value *SimplifyAndInst(Value *, Value *, const SimplifyQuery &, unsigned);
+static Value *simplifyUnOp(unsigned, Value *, const SimplifyQuery &, unsigned);
+static Value *simplifyFPUnOp(unsigned, Value *, const FastMathFlags &,
+                             const SimplifyQuery &, unsigned);
 static Value *SimplifyBinOp(unsigned, Value *, Value *, const SimplifyQuery &,
                             unsigned);
 static Value *SimplifyFPBinOp(unsigned, Value *, Value *, const FastMathFlags &,
@@ -4245,6 +4248,33 @@ Value *llvm::SimplifyShuffleVectorInst(V
   return ::SimplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit);
 }
 
+static Constant *foldConstant(Instruction::UnaryOps Opcode,
+                              Value *&Op, const SimplifyQuery &Q) {
+  if (auto *C = dyn_cast<Constant>(Op))
+    return ConstantFoldUnaryOpOperand(Opcode, C, Q.DL);
+  return nullptr;
+}
+
+/// Given the operand for an FNeg, see if we can fold the result.  If not, this
+/// returns null.
+static Value *simplifyFNegInst(Value *Op, FastMathFlags FMF,
+                               const SimplifyQuery &Q, unsigned MaxRecurse) {
+  if (Constant *C = foldConstant(Instruction::FNeg, Op, Q))
+    return C;
+
+  Value *X;
+  // fneg (fneg X) ==> X
+  if (match(Op, m_FNeg(m_Value(X))))
+    return X;
+
+  return nullptr;
+}
+
+Value *llvm::SimplifyFNegInst(Value *Op, FastMathFlags FMF,
+                              const SimplifyQuery &Q) {
+  return ::simplifyFNegInst(Op, FMF, Q, RecursionLimit);
+}
+
 static Constant *propagateNaN(Constant *In) {
   // If the input is a vector with undef elements, just return a default NaN.
   if (!In->isNaN())
@@ -4472,6 +4502,38 @@ Value *llvm::SimplifyFRemInst(Value *Op0
 
 //=== Helper functions for higher up the class hierarchy.
 
+/// Given the operand for a UnaryOperator, see if we can fold the result.
+/// If not, this returns null.
+static Value *simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q,
+                           unsigned MaxRecurse) {
+  switch (Opcode) {
+  case Instruction::FNeg:
+    return simplifyFNegInst(Op, FastMathFlags(), Q, MaxRecurse);
+  default:
+    llvm_unreachable("Unexpected opcode");
+  }
+}
+
+/// Given the operand for a UnaryOperator, see if we can fold the result.
+/// If not, this returns null.
+/// In contrast to SimplifyUnOp, try to use FastMathFlag when folding the
+/// result. In case we don't need FastMathFlags, simply fall to SimplifyUnOp.
+static Value *simplifyFPUnOp(unsigned Opcode, Value *Op,
+                             const FastMathFlags &FMF,
+                             const SimplifyQuery &Q, unsigned MaxRecurse) {
+  switch (Opcode) {
+  case Instruction::FNeg:
+    return simplifyFNegInst(Op, FMF, Q, MaxRecurse);
+  default:
+    return simplifyUnOp(Opcode, Op, Q, MaxRecurse);
+  }
+}
+
+Value *llvm::SimplifyFPUnOp(unsigned Opcode, Value *Op, FastMathFlags FMF,
+                            const SimplifyQuery &Q) {
+  return ::simplifyFPUnOp(Opcode, Op, FMF, Q, RecursionLimit);
+}
+
 /// Given operands for a BinaryOperator, see if we can fold the result.
 /// If not, this returns null.
 static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
@@ -4959,6 +5021,9 @@ Value *llvm::SimplifyInstruction(Instruc
   default:
     Result = ConstantFoldInstruction(I, Q.DL, Q.TLI);
     break;
+  case Instruction::FNeg:
+    Result = SimplifyFNegInst(I->getOperand(0), I->getFastMathFlags(), Q);
+    break;
   case Instruction::FAdd:
     Result = SimplifyFAddInst(I->getOperand(0), I->getOperand(1),
                               I->getFastMathFlags(), Q);

Modified: llvm/trunk/test/Analysis/ConstantFolding/fneg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ConstantFolding/fneg.ll?rev=360053&r1=360052&r2=360053&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ConstantFolding/fneg.ll (original)
+++ llvm/trunk/test/Analysis/ConstantFolding/fneg.ll Mon May  6 09:05:10 2019
@@ -17,17 +17,6 @@ define float @fneg_undef() {
   ret float %r
 }
 
-define float @fneg_fneg_var(float %a) {
-; CHECK-LABEL: @fneg_fneg_var(
-; CHECK-NEXT:    [[R:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT:    [[R1:%.*]] = fneg float [[R]]
-; CHECK-NEXT:    ret float [[R1]]
-;
-  %r  = fneg float %a
-  %r1 = fneg float %r
-  ret float %r1
-}
-
 define <4 x float> @fneg_constant_elts_v4f32() {
 ; CHECK-LABEL: @fneg_constant_elts_v4f32(
 ; CHECK-NEXT:    ret <4 x float> <float 0.000000e+00, float -0.000000e+00, float 1.000000e+00, float -1.000000e+00>

Modified: llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll?rev=360053&r1=360052&r2=360053&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll Mon May  6 09:05:10 2019
@@ -1,6 +1,15 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -instsimplify -S | FileCheck %s
 
+define float @fneg_fneg_var(float %a) {
+; CHECK-LABEL: @fneg_fneg_var(
+; CHECK-NEXT:    ret float [[A:%.*]]
+;
+  %r  = fneg float %a
+  %r1 = fneg float %r
+  ret float %r1
+}
+
 define <2 x float> @fsub_negzero_vec_undef_elts(<2 x float> %x) {
 ; CHECK-LABEL: @fsub_negzero_vec_undef_elts(
 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]




More information about the llvm-commits mailing list