-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cast from f64 to f32 not working with latest nightly on Windows #13429
Comments
Hm, something odd is going on here. If I break on the Looking at the binary, this sequence of instructions happens for
Note the overlapping stores here (both storing into I suspect an LLVM bug here... |
It'd be interesting to see what clang on windows does. |
Probably just-a-bug. Probably worth investigating. Probably not worth blocking the release, though. |
P-high, not 1.0 milestone. |
So I was able to reduce it to this IR: ; ModuleID = 'bad-float-cast.rs'
target datalayout = "e-p:32:32-i64:64-f80:32-n8:16:32"
target triple = "i686-pc-windows-gnu"
%str_slice = type { i8*, i32 }
@str147 = internal constant [4 x i8] c"%f\0A\00"
declare i32 @printf(i8*, double %f) unnamed_addr
; Function Attrs: uwtable
define internal void @print_double(double %f) unnamed_addr {
entry-block:
%0 = getelementptr inbounds [4 x i8]* @str147, i32 0, i32 0
call i32 @printf(i8* %0, double %f)
ret void
}
define i32 @main(i32, i8**) unnamed_addr {
entry-block:
%a = alloca double
%b = alloca float
store double 3.140000e+00, double* %a
%2 = load double* %a
%3 = fptrunc double %2 to float
store float %3, float* %b
%4 = load float* %b
%5 = fpext float %4 to double
call void @print_double(double %5)
ret i32 0
} Running this through
But notice if I feed the IR to clang directly instead:
So, I'm pretty sure this is an LLVM bug and it's not present in whatever version my clang was built with:
|
This is also not windows specific, I was able to reproduce on both linux and mac. |
I bisected LLVM to find the offending commit: llvm-mirror/llvm@6bb00df but I don't think this caused it so much as just exposed a bug. After that commit, it'd no longer try to autodetect the cpu features supported. If you manually enable sse2 with
|
As for why LLVM is generating bad code in the non-sse case, I've no idea. A small test case to show the bad asm: ; ModuleID = 'bad-float-cast.rs'
target triple = "i686-unknown-linux-gnu"
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 SSE: .text
.file "test.ll"
.globl bar
.align 16, 0x90
.type bar,@function
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
.Ltmp1:
.size bar, .Ltmp1-bar
.cfi_endproc
.section ".note.GNU-stack","",@progbits With sse2: .text
.file "test.ll"
.globl bar
.align 16, 0x90
.type bar,@function
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
.Ltmp1:
.size bar, .Ltmp1-bar
.cfi_endproc
.section ".note.GNU-stack","",@progbits |
Fix submitted upstream: http://reviews.llvm.org/D5125 |
I'm compiling the following program with the latest nightly binary for Windows (with gcc 4.7.2):
This prints
126443840048f32
instead of3.14f32
.If I change the code to the following, it does work as expected:
The text was updated successfully, but these errors were encountered: