[PATCH] Don't generate 64-bit movd after cmpneqsd in 32-bit mode (PR19059)
Hans Wennborg
hans at chromium.org
Mon Mar 10 17:09:02 PDT 2014
Try to clarify the code in X86ISelLowering.cpp a little.
Hi craig.topper,
http://llvm-reviews.chandlerc.com/D3009
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D3009?vs=7718&id=7725#toc
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
@@ -14050,6 +14050,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";
@@ -18056,9 +18057,23 @@
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 = is64BitFP ? MVT::i64 : MVT::i32;
+
+ SDValue OnesOrZeroesI;
+ if (is64BitFP && !Subtarget->is64Bit()) {
+ // On a 32-bit target, we cannot bitcast the 64-bit float to a
+ // 64-bit integer, since that's not a legal type for the target.
+ // Since OnesOrZeroesF is all ones or all zeroes, we don't need all
+ // the bits, but can move just the low bits to a 32-bit integer and
+ // work with that going forward.
+ IntVT = MVT::i32;
+ 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,22 +1,46 @@
-; 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-LABEL: isint_return:
; CHECK-NOT: xor
; CHECK: cvt
%i = fptosi double %d to i32
; CHECK-NEXT: cvt
%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: andl
+ %z = zext i1 %c to i32
+ ret i32 %z
+}
+
+define i32 @isint_float_return(float %f) nounwind {
+; CHECK-LABEL: isint_float_return:
+; CHECK-NOT: xor
+; CHECK: cvt
+ %i = fptosi float %f to i32
+; CHECK-NEXT: cvt
+ %g = sitofp i32 %i to float
+; CHECK: cmpeqss
+ %c = fcmp oeq float %f, %g
+; CHECK-NOT: movd {{.*}}, %r{{.*}}
; CHECK-NEXT: movd
-; CHECK-NEXT: andq
+; CHECK-NEXT: andl
%z = zext i1 %c to i32
ret i32 %z
}
declare void @foo()
define void @isint_branch(double %d) nounwind {
+; CHECK-LABEL: isint_branch:
; CHECK: cvt
%i = fptosi double %d to i32
; CHECK-NEXT: cvt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3009.3.patch
Type: text/x-patch
Size: 5078 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140310/5f83011e/attachment.bin>
More information about the llvm-commits
mailing list