llvm.org GIT mirror llvm / 2b6cbbd
[FastISel][X86] If selectFNeg fails, fall back to SelectionDAG not treating it as an fsub. Summary: If fneg lowering for fsub -0.0, x fails we currently fall back to treating it as an fsub. This has different behavior for nans than the xor with sign bit trick we normally try to do. On X86, the xor trick for double fails fast-isel in 32-bit mode with sse2 due to 64 bit integer types not being available. With -O2 we would always use an xorpd for this case. If we use subsd, this creates an observable behavior difference between -O0 and -O2. So fall back to SelectionDAG if we can't fast-isel it, that way SelectionDAG will use the xorpd. I believe this patch is restoring the behavior prior to r345295 from last October. This was missed then because our fast isel case in 32-bit mode aborted fast-isel earlier for another reason. But I've added new tests to cover that. Reviewers: andrew.w.kaylor, cameron.mcinally, spatel, efriedma Reviewed By: cameron.mcinally Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D61622 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360111 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 6 months ago
3 changed file(s) with 12 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
526526 /// Select and emit code for a binary operator instruction, which has
527527 /// an opcode which directly corresponds to the given ISD opcode.
528528 bool selectBinaryOp(const User *I, unsigned ISDOpcode);
529 bool selectFNeg(const User *I);
529 bool selectFNeg(const User *I, const Value *In);
530530 bool selectGetElementPtr(const User *I);
531531 bool selectStackmap(const CallInst *I);
532532 bool selectPatchpoint(const CallInst *I);
17111711 }
17131713 /// Emit an FNeg operation.
1714 bool FastISel::selectFNeg(const User *I) {
1715 Value *X;
1716 if (!match(I, m_FNeg(m_Value(X))))
1717 return false;
1718 unsigned OpReg = getRegForValue(X);
1714 bool FastISel::selectFNeg(const User *I, const Value *In) {
1715 unsigned OpReg = getRegForValue(In);
17191716 if (!OpReg)
17201717 return false;
1721 bool OpRegIsKill = hasTrivialKill(X);
1718 bool OpRegIsKill = hasTrivialKill(In);
17231720 // If the target has ISD::FNEG, use it.
17241721 EVT VT = TLI.getValueType(DL, I->getType());
18051802 return selectBinaryOp(I, ISD::FADD);
18061803 case Instruction::Sub:
18071804 return selectBinaryOp(I, ISD::SUB);
1808 case Instruction::FSub:
1805 case Instruction::FSub: {
18091806 // FNeg is currently represented in LLVM IR as a special case of FSub.
1810 return selectFNeg(I) || selectBinaryOp(I, ISD::FSUB);
1807 Value *X;
1808 if (match(I, m_FNeg(m_Value(X))))
1809 return selectFNeg(I, X);
1810 return selectBinaryOp(I, ISD::FSUB);
1811 }
18111812 case Instruction::Mul:
18121813 return selectBinaryOp(I, ISD::MUL);
18131814 case Instruction::FMul:
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
11 ; RUN: llc < %s -fast-isel -fast-isel-abort=3 -mtriple=x86_64-apple-darwin10 | FileCheck %s
2 ; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=i686-- -mattr=+sse2 | FileCheck --check-prefix=SSE2 %s
2 ; RUN: llc < %s -fast-isel -mtriple=i686-- -mattr=+sse2 | FileCheck --check-prefix=SSE2 %s
44 define double @doo(double %x) nounwind {
55 ; CHECK-LABEL: doo:
6464 ; SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
6565 ; SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx
6666 ; SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
67 ; SSE2-NEXT: subsd (%ecx), %xmm0
67 ; SSE2-NEXT: xorps {{\.LCPI.*}}, %xmm0
6868 ; SSE2-NEXT: movsd %xmm0, (%eax)
6969 ; SSE2-NEXT: retl
7070 %a = load double, double* %x