1271931SdimPull in r217410 from upstream llvm trunk (by Bob Wilson):
2271931Sdim
3271931Sdim  Set trunc store action to Expand for all X86 targets.
4271931Sdim
5271931Sdim  When compiling without SSE2, isTruncStoreLegal(F64, F32) would return
6271931Sdim  Legal, whereas with SSE2 it would return Expand. And since the Target
7271931Sdim  doesn't seem to actually handle a truncstore for double -> float, it
8271931Sdim  would just output a store of a full double in the space for a float
9271931Sdim  hence overwriting other bits on the stack.
10271931Sdim
11271931Sdim  Patch by Luqman Aden!
12271931Sdim
13271931SdimThis should fix clang -O0 on i386 assigning garbage to floats, in
14271931Sdimcertain scenarios.
15271931Sdim
16271931SdimIntroduced here: http://svnweb.freebsd.org/changeset/base/271597
17271931Sdim
18271931SdimIndex: lib/Target/X86/X86ISelLowering.cpp
19271931Sdim===================================================================
20271931Sdim--- lib/Target/X86/X86ISelLowering.cpp	(revision 208032)
21271931Sdim+++ lib/Target/X86/X86ISelLowering.cpp	(working copy)
22271931Sdim@@ -300,6 +300,8 @@ void X86TargetLowering::resetOperationActions() {
23271931Sdim   setTruncStoreAction(MVT::i32, MVT::i8 , Expand);
24271931Sdim   setTruncStoreAction(MVT::i16, MVT::i8,  Expand);
25271931Sdim 
26271931Sdim+  setTruncStoreAction(MVT::f64, MVT::f32, Expand);
27271931Sdim+
28271931Sdim   // SETOEQ and SETUNE require checking two conditions.
29271931Sdim   setCondCodeAction(ISD::SETOEQ, MVT::f32, Expand);
30271931Sdim   setCondCodeAction(ISD::SETOEQ, MVT::f64, Expand);
31271931Sdim@@ -1011,8 +1013,6 @@ void X86TargetLowering::resetOperationActions() {
32271931Sdim       AddPromotedToType (ISD::SELECT, VT, MVT::v2i64);
33271931Sdim     }
34271931Sdim 
35271931Sdim-    setTruncStoreAction(MVT::f64, MVT::f32, Expand);
36271931Sdim-
37271931Sdim     // Custom lower v2i64 and v2f64 selects.
38271931Sdim     setOperationAction(ISD::LOAD,               MVT::v2f64, Legal);
39271931Sdim     setOperationAction(ISD::LOAD,               MVT::v2i64, Legal);
40271931SdimIndex: test/CodeGen/X86/dont-trunc-store-double-to-float.ll
41271931Sdim===================================================================
42271931Sdim--- test/CodeGen/X86/dont-trunc-store-double-to-float.ll	(revision 0)
43271931Sdim+++ test/CodeGen/X86/dont-trunc-store-double-to-float.ll	(working copy)
44271931Sdim@@ -0,0 +1,20 @@
45271931Sdim+; RUN: llc -march=x86 < %s | FileCheck %s
46271931Sdim+
47271931Sdim+; CHECK-LABEL: @bar
48271931Sdim+; CHECK: movl $1074339512,
49271931Sdim+; CHECK: movl $1374389535,
50271931Sdim+; CHECK: movl $1078523331,
51271931Sdim+define void @bar() unnamed_addr {
52271931Sdim+entry-block:
53271931Sdim+  %a = alloca double
54271931Sdim+  %b = alloca float
55271931Sdim+
56271931Sdim+  store double 3.140000e+00, double* %a
57271931Sdim+  %0 = load double* %a
58271931Sdim+
59271931Sdim+  %1 = fptrunc double %0 to float
60271931Sdim+
61271931Sdim+  store float %1, float* %b
62271931Sdim+
63271931Sdim+  ret void
64271931Sdim+}
65