diff options
| author | Dan Gohman <gohman@apple.com> | 2009-09-03 22:53:57 +0000 |
|---|---|---|
| committer | Dan Gohman <gohman@apple.com> | 2009-09-03 22:53:57 +0000 |
| commit | aa92dc1e6148ae5d1b7c03b98d308958b9f49846 (patch) | |
| tree | 0db85061876eafbf66b04287f5e0e04a43c47dc7 /llvm/lib/CodeGen | |
| parent | 1d5d24545357b0b36b503c9cf08e80d2d719df10 (diff) | |
| download | bcm5719-llvm-aa92dc1e6148ae5d1b7c03b98d308958b9f49846.tar.gz bcm5719-llvm-aa92dc1e6148ae5d1b7c03b98d308958b9f49846.zip | |
LLVM currently represents floating-point negation as -0.0 - x. Fix
FastISel to recognize this pattern and emit a floating-point
negation using xor.
llvm-svn: 80963
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 5b4c79a9fd9..f0c70861843 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -608,6 +608,26 @@ FastISel::FastEmitBranch(MachineBasicBlock *MSucc) { MBB->addSuccessor(MSucc); } +/// SelectFNeg - Emit an FNeg operation. +/// +bool +FastISel::SelectFNeg(User *I) { + unsigned OpReg = getRegForValue(BinaryOperator::getFNegArgument(I)); + if (OpReg == 0) return false; + + // Twiddle the sign bit with xor. + EVT VT = TLI.getValueType(I->getType()); + if (VT.getSizeInBits() > 64) return false; + unsigned ResultReg = FastEmit_ri_(VT.getSimpleVT(), ISD::XOR, OpReg, + UINT64_C(1) << (VT.getSizeInBits()-1), + VT.getSimpleVT()); + if (ResultReg == 0) + return false; + + UpdateValueMap(I, ResultReg); + return true; +} + bool FastISel::SelectOperator(User *I, unsigned Opcode) { switch (Opcode) { @@ -618,6 +638,9 @@ FastISel::SelectOperator(User *I, unsigned Opcode) { case Instruction::Sub: return SelectBinaryOp(I, ISD::SUB); case Instruction::FSub: + // FNeg is currently represented in LLVM IR as a special case of FSub. + if (BinaryOperator::isFNeg(I)) + return SelectFNeg(I); return SelectBinaryOp(I, ISD::FSUB); case Instruction::Mul: return SelectBinaryOp(I, ISD::MUL); |

