llvm.org GIT mirror llvm / a0a0058
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 Cameron McInally 1 year, 5 months ago
4 changed file(s) with 87 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
116116 // deprecated.
117117 // Please use the SimplifyQuery versions in new code.
118118
119 /// Given operand for an FNeg, fold the result or return null.
120 Value *SimplifyFNegInst(Value *Op, FastMathFlags FMF,
121 const SimplifyQuery &Q);
122
119123 /// Given operands for an Add, fold the result or return null.
120124 Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
121125 const SimplifyQuery &Q);
225229 /// Given operands for a CmpInst, fold the result or return null.
226230 Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
227231 const SimplifyQuery &Q);
232
233 /// Given operand for a UnaryOperator, fold the result or return null.
234 Value *SimplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q);
235
236 /// Given operand for an FP UnaryOperator, fold the result or return null.
237 /// In contrast to SimplifyUnOp, try to use FastMathFlag when folding the
238 /// result. In case we don't need FastMathFlags, simply fall to SimplifyUnOp.
239 Value *SimplifyFPUnOp(unsigned Opcode, Value *Op, FastMathFlags FMF,
240 const SimplifyQuery &Q);
228241
229242 /// Given operands for a BinaryOperator, fold the result or return null.
230243 Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
5050 STATISTIC(NumReassoc, "Number of reassociations");
5151
5252 static Value *SimplifyAndInst(Value *, Value *, const SimplifyQuery &, unsigned);
53 static Value *simplifyUnOp(unsigned, Value *, const SimplifyQuery &, unsigned);
54 static Value *simplifyFPUnOp(unsigned, Value *, const FastMathFlags &,
55 const SimplifyQuery &, unsigned);
5356 static Value *SimplifyBinOp(unsigned, Value *, Value *, const SimplifyQuery &,
5457 unsigned);
5558 static Value *SimplifyFPBinOp(unsigned, Value *, Value *, const FastMathFlags &,
42444247 return ::SimplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit);
42454248 }
42464249
4250 static Constant *foldConstant(Instruction::UnaryOps Opcode,
4251 Value *&Op, const SimplifyQuery &Q) {
4252 if (auto *C = dyn_cast(Op))
4253 return ConstantFoldUnaryOpOperand(Opcode, C, Q.DL);
4254 return nullptr;
4255 }
4256
4257 /// Given the operand for an FNeg, see if we can fold the result. If not, this
4258 /// returns null.
4259 static Value *simplifyFNegInst(Value *Op, FastMathFlags FMF,
4260 const SimplifyQuery &Q, unsigned MaxRecurse) {
4261 if (Constant *C = foldConstant(Instruction::FNeg, Op, Q))
4262 return C;
4263
4264 Value *X;
4265 // fneg (fneg X) ==> X
4266 if (match(Op, m_FNeg(m_Value(X))))
4267 return X;
4268
4269 return nullptr;
4270 }
4271
4272 Value *llvm::SimplifyFNegInst(Value *Op, FastMathFlags FMF,
4273 const SimplifyQuery &Q) {
4274 return ::simplifyFNegInst(Op, FMF, Q, RecursionLimit);
4275 }
4276
42474277 static Constant *propagateNaN(Constant *In) {
42484278 // If the input is a vector with undef elements, just return a default NaN.
42494279 if (!In->isNaN())
44704500 }
44714501
44724502 //=== Helper functions for higher up the class hierarchy.
4503
4504 /// Given the operand for a UnaryOperator, see if we can fold the result.
4505 /// If not, this returns null.
4506 static Value *simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q,
4507 unsigned MaxRecurse) {
4508 switch (Opcode) {
4509 case Instruction::FNeg:
4510 return simplifyFNegInst(Op, FastMathFlags(), Q, MaxRecurse);
4511 default:
4512 llvm_unreachable("Unexpected opcode");
4513 }
4514 }
4515
4516 /// Given the operand for a UnaryOperator, see if we can fold the result.
4517 /// If not, this returns null.
4518 /// In contrast to SimplifyUnOp, try to use FastMathFlag when folding the
4519 /// result. In case we don't need FastMathFlags, simply fall to SimplifyUnOp.
4520 static Value *simplifyFPUnOp(unsigned Opcode, Value *Op,
4521 const FastMathFlags &FMF,
4522 const SimplifyQuery &Q, unsigned MaxRecurse) {
4523 switch (Opcode) {
4524 case Instruction::FNeg:
4525 return simplifyFNegInst(Op, FMF, Q, MaxRecurse);
4526 default:
4527 return simplifyUnOp(Opcode, Op, Q, MaxRecurse);
4528 }
4529 }
4530
4531 Value *llvm::SimplifyFPUnOp(unsigned Opcode, Value *Op, FastMathFlags FMF,
4532 const SimplifyQuery &Q) {
4533 return ::simplifyFPUnOp(Opcode, Op, FMF, Q, RecursionLimit);
4534 }
44734535
44744536 /// Given operands for a BinaryOperator, see if we can fold the result.
44754537 /// If not, this returns null.
49585020 default:
49595021 Result = ConstantFoldInstruction(I, Q.DL, Q.TLI);
49605022 break;
5023 case Instruction::FNeg:
5024 Result = SimplifyFNegInst(I->getOperand(0), I->getFastMathFlags(), Q);
5025 break;
49615026 case Instruction::FAdd:
49625027 Result = SimplifyFAddInst(I->getOperand(0), I->getOperand(1),
49635028 I->getFastMathFlags(), Q);
1414 ;
1515 %r = fneg float undef
1616 ret float %r
17 }
18
19 define float @fneg_fneg_var(float %a) {
20 ; CHECK-LABEL: @fneg_fneg_var(
21 ; CHECK-NEXT: [[R:%.*]] = fneg float [[A:%.*]]
22 ; CHECK-NEXT: [[R1:%.*]] = fneg float [[R]]
23 ; CHECK-NEXT: ret float [[R1]]
24 ;
25 %r = fneg float %a
26 %r1 = fneg float %r
27 ret float %r1
2817 }
2918
3019 define <4 x float> @fneg_constant_elts_v4f32() {
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
11 ; RUN: opt < %s -instsimplify -S | FileCheck %s
2
3 define float @fneg_fneg_var(float %a) {
4 ; CHECK-LABEL: @fneg_fneg_var(
5 ; CHECK-NEXT: ret float [[A:%.*]]
6 ;
7 %r = fneg float %a
8 %r1 = fneg float %r
9 ret float %r1
10 }
211
312 define <2 x float> @fsub_negzero_vec_undef_elts(<2 x float> %x) {
413 ; CHECK-LABEL: @fsub_negzero_vec_undef_elts(