[PATCH] Don't generate 64-bit movd after cmpneqsd in 32-bit mode (PR19059)
Hans Wennborg
hans at chromium.org
Fri Mar 7 15:49:19 PST 2014
Hi craig.topper,
This fixes the bug where we would generate 64-bit movd and and instructions after cmpneqsd. Funnily enough, test/CodeGen/X86/isint.ll is an excellent repro for this - it was running in 32-bit mode all along, generating 64-bit instructions and checking for them :)
Please take a careful look, as I'm not very familiar with the codegen layers and I wasn't sure about the best way to do this.
I find it odd that we never hit any asserts while generating 64-bit code for a 32-bit target (and assembling it into something different from our asm printout). Any ideas on how we can fix that are welcome.
http://llvm-reviews.chandlerc.com/D3009
Files:
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrSSE.td
test/CodeGen/X86/isint.ll
Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp
+++ lib/Target/X86/X86ISelLowering.cpp
@@ -14060,6 +14060,7 @@
case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg";
case X86ISD::Wrapper: return "X86ISD::Wrapper";
case X86ISD::WrapperRIP: return "X86ISD::WrapperRIP";
+ case X86ISD::SSE_MOVD2W: return "X86ISD::SSE_MOVD2W";
case X86ISD::PEXTRB: return "X86ISD::PEXTRB";
case X86ISD::PEXTRW: return "X86ISD::PEXTRW";
case X86ISD::INSERTPS: return "X86ISD::INSERTPS";
@@ -18066,9 +18067,17 @@
SDValue OnesOrZeroesF = DAG.getNode(X86ISD::FSETCC, DL,
CMP00.getValueType(), CMP00, CMP01,
DAG.getConstant(x86cc, MVT::i8));
- MVT IntVT = (is64BitFP ? MVT::i64 : MVT::i32);
- SDValue OnesOrZeroesI = DAG.getNode(ISD::BITCAST, DL, IntVT,
- OnesOrZeroesF);
+
+ MVT IntVT = (Subtarget->is64Bit() && is64BitFP ? MVT::i64 : MVT::i32);
+
+ SDValue OnesOrZeroesI;
+ if (is64BitFP && !Subtarget->is64Bit()) {
+ // Move the low half of the 64-bit float to a 32-bit register.
+ OnesOrZeroesI = DAG.getNode(X86ISD::SSE_MOVD2W, DL, IntVT, OnesOrZeroesF);
+ } else {
+ OnesOrZeroesI = DAG.getNode(ISD::BITCAST, DL, IntVT, OnesOrZeroesF);
+ }
+
SDValue ANDed = DAG.getNode(ISD::AND, DL, IntVT, OnesOrZeroesI,
DAG.getConstant(1, IntVT));
SDValue OneBitOfTruth = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, ANDed);
Index: lib/Target/X86/X86ISelLowering.h
===================================================================
--- lib/Target/X86/X86ISelLowering.h
+++ lib/Target/X86/X86ISelLowering.h
@@ -153,6 +153,10 @@
/// vector to a GPR.
MMX_MOVD2W,
+ /// SSE_MOVD2W - Copies a 32-bit value from the low word of a 64-bit float
+ /// to a 32-bit GPR.
+ SSE_MOVD2W,
+
/// PEXTRB - Extract an 8-bit value from a vector and zero extend it to
/// i32, corresponds to X86::PEXTRB.
PEXTRB,
Index: lib/Target/X86/X86InstrSSE.td
===================================================================
--- lib/Target/X86/X86InstrSSE.td
+++ lib/Target/X86/X86InstrSSE.td
@@ -4815,6 +4815,20 @@
}
//===---------------------------------------------------------------------===//
+// Bitcast FR64 <-> GR32
+//
+
+def SSE_X86movd2w : SDNode<"X86ISD::SSE_MOVD2W", SDTypeProfile<1, 1,
+ [SDTCisVT<0, i32>, SDTCisVT<1, f64>]>>;
+
+let isCodeGenOnly = 1 in {
+def MOVSS2Irr : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR64:$src),
+ "movd\t{$src, $dst|$dst, $src}",
+ [(set GR32:$dst, (SSE_X86movd2w FR64:$src))],
+ IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
+}
+
+//===---------------------------------------------------------------------===//
// Patterns and instructions to describe movd/movq to XMM register zero-extends
//
let isCodeGenOnly = 1, SchedRW = [WriteMove] in {
Index: test/CodeGen/X86/isint.ll
===================================================================
--- test/CodeGen/X86/isint.ll
+++ test/CodeGen/X86/isint.ll
@@ -1,4 +1,8 @@
-; RUN: llc < %s -march=x86 -mattr=+sse2 -mcpu=penryn| FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-pc-unknown -mattr=+sse2 -mcpu=penryn | FileCheck %s
+; RUN: llc < %s -mtriple=i686-pc-unknown -mattr=+sse2 -mcpu=penryn | FileCheck %s
+
+; PR19059
+; RUN: llc < %s -mtriple=i686-pc-unknown -mattr=+sse2 -mcpu=penryn | FileCheck -check-prefix=CHECK32 %s
define i32 @isint_return(double %d) nounwind {
; CHECK-NOT: xor
@@ -8,8 +12,10 @@
%e = sitofp i32 %i to double
; CHECK: cmpeqsd
%c = fcmp oeq double %d, %e
+; CHECK32-NOT: movd {{.*}}, %r{{.*}}
+; CHECK32-NOT: andq
; CHECK-NEXT: movd
-; CHECK-NEXT: andq
+; CHECK-NEXT: andl
%z = zext i1 %c to i32
ret i32 %z
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3009.1.patch
Type: text/x-patch
Size: 4127 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140307/ac11f243/attachment.bin>
More information about the llvm-commits
mailing list