llvm.org GIT mirror llvm / 3d45a85
LLVM currently represents floating-point negation as -0.0 - x. Fix FastISel to recognize this pattern and emit a floating-point negation using xor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80963 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 11 years ago
3 changed file(s) with 40 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
299299 private:
300300 bool SelectBinaryOp(User *I, ISD::NodeType ISDOpcode);
301301
302 bool SelectFNeg(User *I);
303
302304 bool SelectGetElementPtr(User *I);
303305
304306 bool SelectCall(User *I);
607607 MBB->addSuccessor(MSucc);
608608 }
609609
610 /// SelectFNeg - Emit an FNeg operation.
611 ///
612 bool
613 FastISel::SelectFNeg(User *I) {
614 unsigned OpReg = getRegForValue(BinaryOperator::getFNegArgument(I));
615 if (OpReg == 0) return false;
616
617 // Twiddle the sign bit with xor.
618 EVT VT = TLI.getValueType(I->getType());
619 if (VT.getSizeInBits() > 64) return false;
620 unsigned ResultReg = FastEmit_ri_(VT.getSimpleVT(), ISD::XOR, OpReg,
621 UINT64_C(1) << (VT.getSizeInBits()-1),
622 VT.getSimpleVT());
623 if (ResultReg == 0)
624 return false;
625
626 UpdateValueMap(I, ResultReg);
627 return true;
628 }
629
610630 bool
611631 FastISel::SelectOperator(User *I, unsigned Opcode) {
612632 switch (Opcode) {
617637 case Instruction::Sub:
618638 return SelectBinaryOp(I, ISD::SUB);
619639 case Instruction::FSub:
640 // FNeg is currently represented in LLVM IR as a special case of FSub.
641 if (BinaryOperator::isFNeg(I))
642 return SelectFNeg(I);
620643 return SelectBinaryOp(I, ISD::FSUB);
621644 case Instruction::Mul:
622645 return SelectBinaryOp(I, ISD::MUL);
0 ; RUN: llvm-as < %s | llc -fast-isel -march=x86-64 | FileCheck %s
1
2 ; CHECK: doo:
3 ; CHECK: xorpd
4 define double @doo(double %x) nounwind {
5 %y = fsub double -0.0, %x
6 ret double %y
7 }
8
9 ; CHECK: foo:
10 ; CHECK: xorps
11 define float @foo(float %x) nounwind {
12 %y = fsub float -0.0, %x
13 ret float %y
14 }