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
retlWith 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