[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