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