<div dir="ltr">I was sort of wondering if we could scalar_to_vector this to a vector with the right sized elements, bitcast that to an f32 vector, then extract element on that. I'll admit its rather convoluted.</div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Mon, Mar 10, 2014 at 5:09 PM, Hans Wennborg <span dir="ltr"><<a href="mailto:hans@chromium.org" target="_blank">hans@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  Try to clarify the code in X86ISelLowering.cpp a little.<br>
<div class=""><br>
Hi craig.topper,<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D3009" target="_blank">http://llvm-reviews.chandlerc.com/D3009</a><br>
<br>
CHANGE SINCE LAST DIFF<br>
</div>  <a href="http://llvm-reviews.chandlerc.com/D3009?vs=7718&id=7725#toc" target="_blank">http://llvm-reviews.chandlerc.com/D3009?vs=7718&id=7725#toc</a><br>
<div class=""><br>
Files:<br>
  lib/Target/X86/X86ISelLowering.cpp<br>
  lib/Target/X86/X86ISelLowering.h<br>
  lib/Target/X86/X86InstrSSE.td<br>
  test/CodeGen/X86/isint.ll<br>
<br>
Index: lib/Target/X86/X86ISelLowering.cpp<br>
===================================================================<br>
--- lib/Target/X86/X86ISelLowering.cpp<br>
+++ lib/Target/X86/X86ISelLowering.cpp<br>
</div>@@ -14050,6 +14050,7 @@<br>
<div class="">   case X86ISD::GlobalBaseReg:      return "X86ISD::GlobalBaseReg";<br>
   case X86ISD::Wrapper:            return "X86ISD::Wrapper";<br>
   case X86ISD::WrapperRIP:         return "X86ISD::WrapperRIP";<br>
+  case X86ISD::SSE_MOVD2W:         return "X86ISD::SSE_MOVD2W";<br>
   case X86ISD::PEXTRB:             return "X86ISD::PEXTRB";<br>
   case X86ISD::PEXTRW:             return "X86ISD::PEXTRW";<br>
   case X86ISD::INSERTPS:           return "X86ISD::INSERTPS";<br>
</div>@@ -18056,9 +18057,23 @@<br>
<div class="">           SDValue OnesOrZeroesF = DAG.getNode(X86ISD::FSETCC, DL,<br>
                                               CMP00.getValueType(), CMP00, CMP01,<br>
                                               DAG.getConstant(x86cc, MVT::i8));<br>
-          MVT IntVT = (is64BitFP ? MVT::i64 : MVT::i32);<br>
-          SDValue OnesOrZeroesI = DAG.getNode(ISD::BITCAST, DL, IntVT,<br>
-                                              OnesOrZeroesF);<br>
+<br>
</div>+          MVT IntVT = is64BitFP ? MVT::i64 : MVT::i32;<br>
<div class="">+<br>
+          SDValue OnesOrZeroesI;<br>
+          if (is64BitFP && !Subtarget->is64Bit()) {<br>
</div>+            // On a 32-bit target, we cannot bitcast the 64-bit float to a<br>
+            // 64-bit integer, since that's not a legal type for the target.<br>
+            // Since OnesOrZeroesF is all ones or all zeroes, we don't need all<br>
+            // the bits, but can move just the low bits to a 32-bit integer and<br>
+            // work with that going forward.<br>
+            IntVT = MVT::i32;<br>
<div><div class="h5">+            OnesOrZeroesI = DAG.getNode(X86ISD::SSE_MOVD2W, DL, IntVT,<br>
+                                        OnesOrZeroesF);<br>
+          } else {<br>
+            OnesOrZeroesI = DAG.getNode(ISD::BITCAST, DL, IntVT, OnesOrZeroesF);<br>
+          }<br>
+<br>
           SDValue ANDed = DAG.getNode(ISD::AND, DL, IntVT, OnesOrZeroesI,<br>
                                       DAG.getConstant(1, IntVT));<br>
           SDValue OneBitOfTruth = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, ANDed);<br>
Index: lib/Target/X86/X86ISelLowering.h<br>
===================================================================<br>
--- lib/Target/X86/X86ISelLowering.h<br>
+++ lib/Target/X86/X86ISelLowering.h<br>
@@ -153,6 +153,10 @@<br>
       /// vector to a GPR.<br>
       MMX_MOVD2W,<br>
<br>
+      /// SSE_MOVD2W - Copies a 32-bit value from the low word of a 64-bit float<br>
+      /// to a 32-bit GPR.<br>
+      SSE_MOVD2W,<br>
+<br>
       /// PEXTRB - Extract an 8-bit value from a vector and zero extend it to<br>
       /// i32, corresponds to X86::PEXTRB.<br>
       PEXTRB,<br>
Index: lib/Target/X86/X86InstrSSE.td<br>
===================================================================<br>
--- lib/Target/X86/X86InstrSSE.td<br>
+++ lib/Target/X86/X86InstrSSE.td<br>
@@ -4815,6 +4815,20 @@<br>
 }<br>
<br>
 //===---------------------------------------------------------------------===//<br>
+// Bitcast FR64 <-> GR32<br>
+//<br>
+<br>
+def SSE_X86movd2w : SDNode<"X86ISD::SSE_MOVD2W", SDTypeProfile<1, 1,<br>
+                           [SDTCisVT<0, i32>, SDTCisVT<1, f64>]>>;<br>
+<br>
+let isCodeGenOnly = 1 in {<br>
+def MOVSS2Irr : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR64:$src),<br>
+                    "movd\t{$src, $dst|$dst, $src}",<br>
+                    [(set GR32:$dst, (SSE_X86movd2w FR64:$src))],<br>
+                    IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;<br>
+}<br>
+<br>
+//===---------------------------------------------------------------------===//<br>
 // Patterns and instructions to describe movd/movq to XMM register zero-extends<br>
 //<br>
 let isCodeGenOnly = 1, SchedRW = [WriteMove] in {<br>
Index: test/CodeGen/X86/isint.ll<br>
===================================================================<br>
--- test/CodeGen/X86/isint.ll<br>
+++ test/CodeGen/X86/isint.ll<br>
</div></div>@@ -1,22 +1,46 @@<br>
<div class="">-; RUN: llc < %s -march=x86 -mattr=+sse2 -mcpu=penryn| FileCheck %s<br>
+; RUN: llc < %s -mtriple=x86_64-pc-unknown -mattr=+sse2 -mcpu=penryn | FileCheck %s<br>
+; RUN: llc < %s -mtriple=i686-pc-unknown -mattr=+sse2 -mcpu=penryn | FileCheck %s<br>
+<br>
+; PR19059<br>
+; RUN: llc < %s -mtriple=i686-pc-unknown -mattr=+sse2 -mcpu=penryn | FileCheck -check-prefix=CHECK32 %s<br>
<br>
 define i32 @isint_return(double %d) nounwind {<br>
</div><div class="">+; CHECK-LABEL: isint_return:<br>
 ; CHECK-NOT: xor<br>
 ; CHECK: cvt<br>
   %i = fptosi double %d to i32<br>
 ; CHECK-NEXT: cvt<br>
</div><div class="">   %e = sitofp i32 %i to double<br>
 ; CHECK: cmpeqsd<br>
   %c = fcmp oeq double %d, %e<br>
+; CHECK32-NOT: movd {{.*}}, %r{{.*}}<br>
+; CHECK32-NOT: andq<br>
</div><div class="">+; CHECK-NEXT: movd<br>
+; CHECK-NEXT: andl<br>
+  %z = zext i1 %c to i32<br>
+  ret i32 %z<br>
+}<br>
+<br>
+define i32 @isint_float_return(float %f) nounwind {<br>
+; CHECK-LABEL: isint_float_return:<br>
+; CHECK-NOT: xor<br>
+; CHECK: cvt<br>
+  %i = fptosi float %f to i32<br>
+; CHECK-NEXT: cvt<br>
+  %g = sitofp i32 %i to float<br>
+; CHECK: cmpeqss<br>
+  %c = fcmp oeq float %f, %g<br>
</div>+; CHECK-NOT: movd {{.*}}, %r{{.*}}<br>
<div class="im HOEnZb"> ; CHECK-NEXT: movd<br>
-; CHECK-NEXT: andq<br>
+; CHECK-NEXT: andl<br>
   %z = zext i1 %c to i32<br>
   ret i32 %z<br>
 }<br>
<br>
</div><div class="HOEnZb"><div class="h5"> declare void @foo()<br>
<br>
 define void @isint_branch(double %d) nounwind {<br>
+; CHECK-LABEL: isint_branch:<br>
 ; CHECK: cvt<br>
   %i = fptosi double %d to i32<br>
 ; CHECK-NEXT: cvt<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>~Craig
</div>