https://llvm.org/bugs/show_bug.cgi?id=24343
Bug ID: 24343 Summary: After r228826, fdiv can be hoisted incorrectly on i386 Product: new-bugs Version: trunk Hardware: PC OS: All Status: NEW Severity: normal Priority: P Component: new bugs Assignee: unassignedb...@nondot.org Reporter: dimi...@andric.com CC: llvmbugs@cs.uiuc.edu Classification: Unclassified During a mass test build of the FreeBSD ports collection with a recent clang trunk snapshot, we ran into strange libpng failures on i386: http://package18.nyi.freebsd.org/data/headi386PR201377-default/2015-07-31_12h04m22s/logs/errors/png-1.6.17_1.log After some digging, it turned out that the failing tests get a 'division by zero' floating point exception, when calling pow() with a 0 first argument. Note that all libpng tests enable such floating point exceptions using feenableexcept(3). The FPE occurs in the following part of pow()'s FreeBSD implementation, on line 166: 161 /* special value of x */ 162 if(lx==0) { 163 if(ix==0x7ff00000||ix==0||ix==0x3ff00000){ 164 z = ax; /*x is +-0,+-inf,+-1*/ 165 if(hy<0) 166 z = 1.0/z; /* z = (1/|x|) */ 167 if(hx<0) { 168 if(((ix-0x3ff00000)|yisint)==0) { 169 z = (z-z)/(z-z); /* (-1)**non-int is NaN */ 170 } else if(yisint==1) 171 z = -z; /* (x<0)**odd = -(|x|**odd) */ 172 } 173 return z; 174 } 175 } However, for the particular tests, at line 165 'hy' is zero, so line 166 should really have been skipped. But inspection of the assembly (in this case produced by trunk r241361) shows that the fdiv has been incorrectly hoisted above the conditional jump (js .LBB_024): .Ltmp96: #DEBUG_VALUE: pow:ix <- ESI #DEBUG_VALUE: pow:yisint <- 0 #DEBUG_VALUE: pow:z <- FP3 #DEBUG_VALUE: pow:ax <- FP3 .loc 1 165 8 is_stmt 1 # e_pow.c:165:8 cmpl $0, 36(%esp) # 4-byte Folded Reload .loc 1 166 14 # e_pow.c:166:14 fld1 fdiv %st(1) .Ltmp97: #DEBUG_VALUE: pow:z <- FP1 js .LBB0_24 .Ltmp98: # BB#23: # %if.then.107 fstp %st(0) Compare this with the correct output of clang 3.6.1, where the fdiv is only done in case the conditional fails: .Ltmp101: #DEBUG_VALUE: pow:ix <- ESI #DEBUG_VALUE: pow:yisint <- 0 #DEBUG_VALUE: pow:z <- FP1 #DEBUG_VALUE: pow:ax <- FP1 .loc 1 165 6 is_stmt 1 # e_pow.c:165:6 cmpl $0, 36(%esp) # 4-byte Folded Reload jns .LBB0_24 .Ltmp102: # BB#23: # %if.then108 #DEBUG_VALUE: pow:ix <- ESI #DEBUG_VALUE: pow:yisint <- 0 #DEBUG_VALUE: pow:z <- FP1 #DEBUG_VALUE: pow:ax <- FP1 fld1 .loc 1 166 11 # e_pow.c:166:11 .Ltmp103: fdivp %st(1) .Ltmp104: .LBB0_24: # %if.end110 Bisecting showed that this invalid hoisting has been introduced by r228826, "[SimplifyCFG] Swap to using TargetTransformInfo for cost analysis". I am unsure why, though; it does not seem to touch i387 FP code directly? Here is a minimal C test case to show the issue; it can also be run to show the FPE: #include <fenv.h> __attribute__((__noinline__)) double foo(int n, double d) { if (n > 0) d = 1.0 / d; return d; } int main(void) { feenableexcept(FE_DIVBYZERO); return (int)foo(0, 0.0); } Compile this with: clang -target i386-freebsd -O2 -S bad-hoist.c Correct result with clang at r228825: foo: # @foo # BB#0: # %entry pushl %ebp movl %esp, %ebp fldl 12(%ebp) cmpl $0, 8(%ebp) jle .LBB0_2 # BB#1: # %if.then fld1 fdivp %st(1) .LBB0_2: # %if.end Bad result with clang at r228826: foo: # @foo # BB#0: # %entry pushl %ebp movl %esp, %ebp fldl 12(%ebp) cmpl $0, 8(%ebp) fld1 fdiv %st(1) jg .LBB0_2 # BB#1: # %entry fstp %st(0) fldz fxch %st(1) .LBB0_2: # %entry -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ LLVMbugs mailing list LLVMbugs@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvmbugs