Skip to content

Commit

Permalink
[FastISel][X86] If selectFNeg fails, fall back to SelectionDAG not tr…
Browse files Browse the repository at this point in the history
…eating 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

llvm-svn: 360111
  • Loading branch information
topperc authored and MrSidims committed May 17, 2019
1 parent 665a4a6 commit 46a69bd
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 11 deletions.
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/FastISel.h
Expand Up @@ -527,7 +527,7 @@ class FastISel {
/// Select and emit code for a binary operator instruction, which has
/// an opcode which directly corresponds to the given ISD opcode.
bool selectBinaryOp(const User *I, unsigned ISDOpcode);
bool selectFNeg(const User *I);
bool selectFNeg(const User *I, const Value *In);
bool selectGetElementPtr(const User *I);
bool selectStackmap(const CallInst *I);
bool selectPatchpoint(const CallInst *I);
Expand Down
17 changes: 9 additions & 8 deletions llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
Expand Up @@ -1712,14 +1712,11 @@ void FastISel::finishCondBranch(const BasicBlock *BranchBB,
}

/// Emit an FNeg operation.
bool FastISel::selectFNeg(const User *I) {
Value *X;
if (!match(I, m_FNeg(m_Value(X))))
return false;
unsigned OpReg = getRegForValue(X);
bool FastISel::selectFNeg(const User *I, const Value *In) {
unsigned OpReg = getRegForValue(In);
if (!OpReg)
return false;
bool OpRegIsKill = hasTrivialKill(X);
bool OpRegIsKill = hasTrivialKill(In);

// If the target has ISD::FNEG, use it.
EVT VT = TLI.getValueType(DL, I->getType());
Expand Down Expand Up @@ -1806,9 +1803,13 @@ bool FastISel::selectOperator(const User *I, unsigned Opcode) {
return selectBinaryOp(I, ISD::FADD);
case Instruction::Sub:
return selectBinaryOp(I, ISD::SUB);
case Instruction::FSub:
case Instruction::FSub: {
// FNeg is currently represented in LLVM IR as a special case of FSub.
return selectFNeg(I) || selectBinaryOp(I, ISD::FSUB);
Value *X;
if (match(I, m_FNeg(m_Value(X))))
return selectFNeg(I, X);
return selectBinaryOp(I, ISD::FSUB);
}
case Instruction::Mul:
return selectBinaryOp(I, ISD::MUL);
case Instruction::FMul:
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/X86/fast-isel-fneg.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -fast-isel -fast-isel-abort=3 -mtriple=x86_64-apple-darwin10 | FileCheck %s
; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=i686-- -mattr=+sse2 | FileCheck --check-prefix=SSE2 %s
; RUN: llc < %s -fast-isel -mtriple=i686-- -mattr=+sse2 | FileCheck --check-prefix=SSE2 %s

define double @doo(double %x) nounwind {
; CHECK-LABEL: doo:
Expand Down Expand Up @@ -65,7 +65,7 @@ define void @goo(double* %x, double* %y) nounwind {
; SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
; SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx
; SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
; SSE2-NEXT: subsd (%ecx), %xmm0
; SSE2-NEXT: xorps {{\.LCPI.*}}, %xmm0
; SSE2-NEXT: movsd %xmm0, (%eax)
; SSE2-NEXT: retl
%a = load double, double* %x
Expand Down

0 comments on commit 46a69bd

Please sign in to comment.