1Pull in r217410 from upstream llvm trunk (by Bob Wilson):
2
3  Set trunc store action to Expand for all X86 targets.
4
5  When compiling without SSE2, isTruncStoreLegal(F64, F32) would return
6  Legal, whereas with SSE2 it would return Expand. And since the Target
7  doesn't seem to actually handle a truncstore for double -> float, it
8  would just output a store of a full double in the space for a float
9  hence overwriting other bits on the stack.
10
11  Patch by Luqman Aden!
12
13This should fix clang -O0 on i386 assigning garbage to floats, in
14certain scenarios.
15
16Introduced here: http://svnweb.freebsd.org/changeset/base/271597
17
18Index: lib/Target/X86/X86ISelLowering.cpp
19===================================================================
20--- lib/Target/X86/X86ISelLowering.cpp	(revision 208032)
21+++ lib/Target/X86/X86ISelLowering.cpp	(working copy)
22@@ -300,6 +300,8 @@ void X86TargetLowering::resetOperationActions() {
23   setTruncStoreAction(MVT::i32, MVT::i8 , Expand);
24   setTruncStoreAction(MVT::i16, MVT::i8,  Expand);
25 
26+  setTruncStoreAction(MVT::f64, MVT::f32, Expand);
27+
28   // SETOEQ and SETUNE require checking two conditions.
29   setCondCodeAction(ISD::SETOEQ, MVT::f32, Expand);
30   setCondCodeAction(ISD::SETOEQ, MVT::f64, Expand);
31@@ -1011,8 +1013,6 @@ void X86TargetLowering::resetOperationActions() {
32       AddPromotedToType (ISD::SELECT, VT, MVT::v2i64);
33     }
34 
35-    setTruncStoreAction(MVT::f64, MVT::f32, Expand);
36-
37     // Custom lower v2i64 and v2f64 selects.
38     setOperationAction(ISD::LOAD,               MVT::v2f64, Legal);
39     setOperationAction(ISD::LOAD,               MVT::v2i64, Legal);
40Index: test/CodeGen/X86/dont-trunc-store-double-to-float.ll
41===================================================================
42--- test/CodeGen/X86/dont-trunc-store-double-to-float.ll	(revision 0)
43+++ test/CodeGen/X86/dont-trunc-store-double-to-float.ll	(working copy)
44@@ -0,0 +1,20 @@
45+; RUN: llc -march=x86 < %s | FileCheck %s
46+
47+; CHECK-LABEL: @bar
48+; CHECK: movl $1074339512,
49+; CHECK: movl $1374389535,
50+; CHECK: movl $1078523331,
51+define void @bar() unnamed_addr {
52+entry-block:
53+  %a = alloca double
54+  %b = alloca float
55+
56+  store double 3.140000e+00, double* %a
57+  %0 = load double* %a
58+
59+  %1 = fptrunc double %0 to float
60+
61+  store float %1, float* %b
62+
63+  ret void
64+}
65