When compiling without SSE2, isTruncStoreLegal(F64, F32) would return Legal, whereas with SSE2 it would return Expand. And since the Target doesn't seem to actually handle a truncstore for double -> float, it would just output a store of a full double in the space for a float hence overwriting other bits on the stack.
define void @bar() unnamed_addr { entry-block: %a = alloca double %b = alloca float store double 3.140000e+00, double* %a %0 = load double* %a %1 = fptrunc double %0 to float store float %1, float* %b ret void }
Without SSE2:
bar: # @bar .cfi_startproc # BB#0: # %entry-block subl $20, %esp .Ltmp0: .cfi_def_cfa_offset 24 movl $1074339512, 12(%esp) # imm = 0x40091EB8 movl $1374389535, 8(%esp) # imm = 0x51EB851F 0x40091EB851EB851F (double) 3.14 movl $1074339512, 8(%esp) # imm = 0x40091EB8 movl $1374389535, 4(%esp) # imm = 0x51EB851F addl $20, %esp retl
With SSE2:
bar: # @bar .cfi_startproc # BB#0: # %entry-block subl $20, %esp .Ltmp0: .cfi_def_cfa_offset 24 movl $1074339512, 12(%esp) # imm = 0x40091EB8 movl $1374389535, 8(%esp) # imm = 0x51EB851F 0x40091EB851EB851F (double) 3.14 movl $1078523331, 4(%esp) # imm = 0x4048F5C3 0x4048F5C3 (float) 3.14 addl $20, %esp retl