summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-09-03 22:53:57 +0000
committerDan Gohman <gohman@apple.com>2009-09-03 22:53:57 +0000
commitaa92dc1e6148ae5d1b7c03b98d308958b9f49846 (patch)
tree0db85061876eafbf66b04287f5e0e04a43c47dc7 /llvm/lib/CodeGen
parent1d5d24545357b0b36b503c9cf08e80d2d719df10 (diff)
downloadbcm5719-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.cpp23
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);
OpenPOWER on IntegriCloud