Skip to content

Commit a0a0058

Browse files
committed
Add FNeg support to InstructionSimplify
Differential Revision: https://reviews.llvm.org/D61573 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360053 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 0f6bb4c commit a0a0058

File tree

4 files changed

+87
-11
lines changed

4 files changed

+87
-11
lines changed

include/llvm/Analysis/InstructionSimplify.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ struct SimplifyQuery {
117117
// deprecated.
118118
// Please use the SimplifyQuery versions in new code.
119119

120+
/// Given operand for an FNeg, fold the result or return null.
121+
Value *SimplifyFNegInst(Value *Op, FastMathFlags FMF,
122+
const SimplifyQuery &Q);
123+
120124
/// Given operands for an Add, fold the result or return null.
121125
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
122126
const SimplifyQuery &Q);
@@ -227,6 +231,15 @@ Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
227231
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
228232
const SimplifyQuery &Q);
229233

234+
/// Given operand for a UnaryOperator, fold the result or return null.
235+
Value *SimplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q);
236+
237+
/// Given operand for an FP UnaryOperator, fold the result or return null.
238+
/// In contrast to SimplifyUnOp, try to use FastMathFlag when folding the
239+
/// result. In case we don't need FastMathFlags, simply fall to SimplifyUnOp.
240+
Value *SimplifyFPUnOp(unsigned Opcode, Value *Op, FastMathFlags FMF,
241+
const SimplifyQuery &Q);
242+
230243
/// Given operands for a BinaryOperator, fold the result or return null.
231244
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
232245
const SimplifyQuery &Q);

lib/Analysis/InstructionSimplify.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ STATISTIC(NumExpand, "Number of expansions");
5151
STATISTIC(NumReassoc, "Number of reassociations");
5252

5353
static Value *SimplifyAndInst(Value *, Value *, const SimplifyQuery &, unsigned);
54+
static Value *simplifyUnOp(unsigned, Value *, const SimplifyQuery &, unsigned);
55+
static Value *simplifyFPUnOp(unsigned, Value *, const FastMathFlags &,
56+
const SimplifyQuery &, unsigned);
5457
static Value *SimplifyBinOp(unsigned, Value *, Value *, const SimplifyQuery &,
5558
unsigned);
5659
static Value *SimplifyFPBinOp(unsigned, Value *, Value *, const FastMathFlags &,
@@ -4245,6 +4248,33 @@ Value *llvm::SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
42454248
return ::SimplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit);
42464249
}
42474250

4251+
static Constant *foldConstant(Instruction::UnaryOps Opcode,
4252+
Value *&Op, const SimplifyQuery &Q) {
4253+
if (auto *C = dyn_cast<Constant>(Op))
4254+
return ConstantFoldUnaryOpOperand(Opcode, C, Q.DL);
4255+
return nullptr;
4256+
}
4257+
4258+
/// Given the operand for an FNeg, see if we can fold the result. If not, this
4259+
/// returns null.
4260+
static Value *simplifyFNegInst(Value *Op, FastMathFlags FMF,
4261+
const SimplifyQuery &Q, unsigned MaxRecurse) {
4262+
if (Constant *C = foldConstant(Instruction::FNeg, Op, Q))
4263+
return C;
4264+
4265+
Value *X;
4266+
// fneg (fneg X) ==> X
4267+
if (match(Op, m_FNeg(m_Value(X))))
4268+
return X;
4269+
4270+
return nullptr;
4271+
}
4272+
4273+
Value *llvm::SimplifyFNegInst(Value *Op, FastMathFlags FMF,
4274+
const SimplifyQuery &Q) {
4275+
return ::simplifyFNegInst(Op, FMF, Q, RecursionLimit);
4276+
}
4277+
42484278
static Constant *propagateNaN(Constant *In) {
42494279
// If the input is a vector with undef elements, just return a default NaN.
42504280
if (!In->isNaN())
@@ -4472,6 +4502,38 @@ Value *llvm::SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
44724502

44734503
//=== Helper functions for higher up the class hierarchy.
44744504

4505+
/// Given the operand for a UnaryOperator, see if we can fold the result.
4506+
/// If not, this returns null.
4507+
static Value *simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q,
4508+
unsigned MaxRecurse) {
4509+
switch (Opcode) {
4510+
case Instruction::FNeg:
4511+
return simplifyFNegInst(Op, FastMathFlags(), Q, MaxRecurse);
4512+
default:
4513+
llvm_unreachable("Unexpected opcode");
4514+
}
4515+
}
4516+
4517+
/// Given the operand for a UnaryOperator, see if we can fold the result.
4518+
/// If not, this returns null.
4519+
/// In contrast to SimplifyUnOp, try to use FastMathFlag when folding the
4520+
/// result. In case we don't need FastMathFlags, simply fall to SimplifyUnOp.
4521+
static Value *simplifyFPUnOp(unsigned Opcode, Value *Op,
4522+
const FastMathFlags &FMF,
4523+
const SimplifyQuery &Q, unsigned MaxRecurse) {
4524+
switch (Opcode) {
4525+
case Instruction::FNeg:
4526+
return simplifyFNegInst(Op, FMF, Q, MaxRecurse);
4527+
default:
4528+
return simplifyUnOp(Opcode, Op, Q, MaxRecurse);
4529+
}
4530+
}
4531+
4532+
Value *llvm::SimplifyFPUnOp(unsigned Opcode, Value *Op, FastMathFlags FMF,
4533+
const SimplifyQuery &Q) {
4534+
return ::simplifyFPUnOp(Opcode, Op, FMF, Q, RecursionLimit);
4535+
}
4536+
44754537
/// Given operands for a BinaryOperator, see if we can fold the result.
44764538
/// If not, this returns null.
44774539
static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
@@ -4959,6 +5021,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const SimplifyQuery &SQ,
49595021
default:
49605022
Result = ConstantFoldInstruction(I, Q.DL, Q.TLI);
49615023
break;
5024+
case Instruction::FNeg:
5025+
Result = SimplifyFNegInst(I->getOperand(0), I->getFastMathFlags(), Q);
5026+
break;
49625027
case Instruction::FAdd:
49635028
Result = SimplifyFAddInst(I->getOperand(0), I->getOperand(1),
49645029
I->getFastMathFlags(), Q);

test/Analysis/ConstantFolding/fneg.ll

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,6 @@ define float @fneg_undef() {
1717
ret float %r
1818
}
1919

20-
define float @fneg_fneg_var(float %a) {
21-
; CHECK-LABEL: @fneg_fneg_var(
22-
; CHECK-NEXT: [[R:%.*]] = fneg float [[A:%.*]]
23-
; CHECK-NEXT: [[R1:%.*]] = fneg float [[R]]
24-
; CHECK-NEXT: ret float [[R1]]
25-
;
26-
%r = fneg float %a
27-
%r1 = fneg float %r
28-
ret float %r1
29-
}
30-
3120
define <4 x float> @fneg_constant_elts_v4f32() {
3221
; CHECK-LABEL: @fneg_constant_elts_v4f32(
3322
; CHECK-NEXT: ret <4 x float> <float 0.000000e+00, float -0.000000e+00, float 1.000000e+00, float -1.000000e+00>

test/Transforms/InstSimplify/floating-point-arithmetic.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt < %s -instsimplify -S | FileCheck %s
33

4+
define float @fneg_fneg_var(float %a) {
5+
; CHECK-LABEL: @fneg_fneg_var(
6+
; CHECK-NEXT: ret float [[A:%.*]]
7+
;
8+
%r = fneg float %a
9+
%r1 = fneg float %r
10+
ret float %r1
11+
}
12+
413
define <2 x float> @fsub_negzero_vec_undef_elts(<2 x float> %x) {
514
; CHECK-LABEL: @fsub_negzero_vec_undef_elts(
615
; CHECK-NEXT: ret <2 x float> [[X:%.*]]

0 commit comments

Comments
 (0)