diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 5194d85ee1e42a..8ed291778da623 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -3371,10 +3371,11 @@ bool llvm::isMathLibCallNoop(const CallBase *Call, case LibFunc_atan2: case LibFunc_atan2f: case LibFunc_atan2l: - // POSIX, GLIBC and MSVC dictate atan2(0,0) is 0 and no error is raised. - // C11 says that a domain error may optionally occur. - // This is consistent with both. - return true; + // Although IEEE-754 says atan2(+/-0.0, +/-0.0) are well-defined, and + // GLIBC and MSVC do not appear to raise an error on those, we + // cannot rely on that behavior. POSIX and C11 say that a domain error + // may occur, so allow for that possibility. + return !Op0.isZero() || !Op1.isZero(); default: break; diff --git a/llvm/test/Transforms/EarlyCSE/atan.ll b/llvm/test/Transforms/EarlyCSE/atan.ll index 11dce636fbbb9e..adb6ff7f5c03e4 100644 --- a/llvm/test/Transforms/EarlyCSE/atan.ll +++ b/llvm/test/Transforms/EarlyCSE/atan.ll @@ -50,32 +50,44 @@ define x86_fp80 @atanl_x86(x86_fp80 %x) { ret x86_fp80 %call } +; This is not folded because it is known to set errno on some systems. + define float @callatan2_00() { ; CHECK-LABEL: @callatan2_00( +; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float 0.000000e+00, float 0.000000e+00) ; CHECK-NEXT: ret float 0.000000e+00 ; %call = call float @atan2f(float 0.0, float 0.0) ret float %call } +; This is not folded because it is known to set errno on some systems. + define float @callatan2_n00() { ; CHECK-LABEL: @callatan2_n00( +; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float -0.000000e+00, float 0.000000e+00) ; CHECK-NEXT: ret float -0.000000e+00 ; %call = call float @atan2f(float -0.0, float 0.0) ret float %call } +; This is not folded because it is known to set errno on some systems. + define float @callatan2_0n0() { ; CHECK-LABEL: @callatan2_0n0( +; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float 0.000000e+00, float -0.000000e+00) ; CHECK-NEXT: ret float 0x400921FB60000000 ; %call = call float @atan2f(float 0.0, float -0.0) ret float %call } +; This is not folded because it is known to set errno on some systems. + define float @callatan2_n0n0() { ; CHECK-LABEL: @callatan2_n0n0( +; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float -0.000000e+00, float -0.000000e+00) ; CHECK-NEXT: ret float 0xC00921FB60000000 ; %call = call float @atan2f(float -0.0, float -0.0)