Skip to content

x86 wrong code for floating point comparison #63055

Closed
@cbeuw

Description

@cbeuw

From rust-lang/rust#112170

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 
target triple = "x86_64-unknown-linux-gnu" 
 
define void @fn1() { 
start: 
  %_6 = fadd double 0.000000e+00, 0.000000e+00 
  br label %bb2.outer1464 
 
bb2.outer1464:                                    ; preds = %bb2.outer1464, %start 
  %0 = icmp eq i32 0, 0 
  br i1 %0, label %bb15.preheader, label %bb2.outer1464 
 
bb15.preheader:                                   ; preds = %bb2.outer1464 
  %_23.le = fcmp une double 0x7FF8000000000000, %_6 
  %_30 = zext i1 %_23.le to i64 
  tail call void @print_var(i64 %_30) 
  ret void 
} 
 
declare void @print_var(i64) 

%_30 should be 1, as NaN != 0 is true, however on x86 print_var gets called with 255:

fn1:                                    # @fn1
        xorps   xmm0, xmm0
        addsd   xmm0, xmm0
        mov     edi, 255
        jmp     print_var@PLT                   # TAILCALL

https://godbolt.org/z/5f447cnfn

opt -O3 is correct:

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define void @fn1() local_unnamed_addr {
  tail call void @print_var(i64 1)
  ret void
}

declare void @print_var(i64) local_unnamed_addr

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions