[PATCH] Don't generate 64-bit movd after cmpneqsd in 32-bit mode (PR19059)

Hans Wennborg hans at chromium.org
Mon Mar 10 14:27:35 PDT 2014


  Might as well add a test for the single precision float case while I'm here.

  Also, ping? :)

Hi craig.topper,

http://llvm-reviews.chandlerc.com/D3009

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D3009?vs=7655&id=7718#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,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,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.2.patch
Type: text/x-patch
Size: 4746 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140310/637c6066/attachment.bin>


More information about the llvm-commits mailing list