diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -3296,6 +3296,13 @@ break; } + case LibFunc_atan: + case LibFunc_atanf: + case LibFunc_atanl: + // Per POSIX, this MAY fail if Op is denormal. We choose not failing. + return true; + + case LibFunc_asinl: case LibFunc_asin: case LibFunc_asinf: @@ -3361,6 +3368,14 @@ return Op0.isNaN() || Op1.isNaN() || (!Op0.isInfinity() && !Op1.isZero()); + 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; + default: break; } diff --git a/llvm/test/Transforms/EarlyCSE/atan.ll b/llvm/test/Transforms/EarlyCSE/atan.ll --- a/llvm/test/Transforms/EarlyCSE/atan.ll +++ b/llvm/test/Transforms/EarlyCSE/atan.ll @@ -4,13 +4,13 @@ define float @callatan0() { ; CHECK-LABEL: @callatan0( -; CHECK-NEXT: [[CALL:%.*]] = call float @atanf(float -0.000000e+00) ; CHECK-NEXT: ret float -0.000000e+00 ; %call = call float @atanf(float -0.0) ret float %call } +; TODO: constant should be folded define float @callatanInf() { ; CHECK-LABEL: @callatanInf( ; CHECK-NEXT: [[CALL:%.*]] = call float @atanf(float 0x7FF0000000000000) @@ -20,6 +20,7 @@ ret float %call } +; TODO: constant should be folded define float @callatanNaN() { ; CHECK-LABEL: @callatanNaN( ; CHECK-NEXT: [[CALL:%.*]] = call float @atanf(float 0x7FF8000000000000) @@ -29,16 +30,16 @@ ret float %call } +; POSIX: May fail with Range Error. We choose not to fail. define float @callatanDenorm() { ; CHECK-LABEL: @callatanDenorm( -; CHECK-NEXT: [[CALL:%.*]] = call float @atanf(float 0x37A16C2000000000) ; CHECK-NEXT: ret float 0x37A16C2000000000 ; %call = call float @atanf(float 0x37A16C2000000000) ret float %call } -; long double calls currently not folded +; TODO: long double calls currently not folded define x86_fp80 @atanl_x86(x86_fp80 %x) { ; CHECK-LABEL: @atanl_x86( ; CHECK-NEXT: [[CALL:%.*]] = call x86_fp80 @atanl(x86_fp80 noundef 0xK3FFF8CCCCCCCCCCCCCCD) @@ -50,7 +51,6 @@ 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) @@ -59,7 +59,6 @@ define float @callatan2_x0() { ; CHECK-LABEL: @callatan2_x0( -; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float 1.000000e+00, float -0.000000e+00) ; CHECK-NEXT: ret float 0x3FF921FB60000000 ; %call = call float @atan2f(float 1.0, float -0.000000e+00) @@ -68,7 +67,6 @@ define float @callatan2_0x() { ; CHECK-LABEL: @callatan2_0x( -; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float -0.000000e+00, float 1.000000e+00) ; CHECK-NEXT: ret float -0.000000e+00 ; %call = call float @atan2f(float -0.0, float 1.0) @@ -77,7 +75,6 @@ define float @callatan2_xx() { ; CHECK-LABEL: @callatan2_xx( -; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float -1.000000e+00, float 1.000000e+00) ; CHECK-NEXT: ret float 0xBFE921FB60000000 ; %call = call float @atan2f(float -1.0, float 1.0) @@ -86,7 +83,6 @@ define float @callatan2_denorm() { ; CHECK-LABEL: @callatan2_denorm( -; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float 0x39B4484C00000000, float 1.000000e+10) ; CHECK-NEXT: ret float 0x37A16C2000000000 ; %call = call float @atan2f(float 0x39B4484C00000000, float 1.0e+10) @@ -95,7 +91,6 @@ define float @callatan2_flush_to_zero() { ; CHECK-LABEL: @callatan2_flush_to_zero( -; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float 0x39B4484C00000000, float 0x4415AF1D80000000) ; CHECK-NEXT: ret float 0.000000e+00 ; %call = call float @atan2f(float 0x39B4484C00000000, float 0x4415AF1D80000000) @@ -104,7 +99,6 @@ define float @callatan2_NaN() { ; CHECK-LABEL: @callatan2_NaN( -; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float 0x7FF8000000000000, float 0x7FF8000000000000) ; CHECK-NEXT: ret float 0x7FF8000000000000 ; %call = call float @atan2f(float 0x7FF8000000000000, float 0x7FF8000000000000) @@ -113,7 +107,6 @@ define float @callatan2_Inf() { ; CHECK-LABEL: @callatan2_Inf( -; CHECK-NEXT: [[CALL:%.*]] = call float @atan2f(float 0x7FF0000000000000, float 0x7FF0000000000000) ; CHECK-NEXT: ret float 0x3FE921FB60000000 ; %call = call float @atan2f(float 0x7FF0000000000000, float 0x7FF0000000000000) diff --git a/llvm/test/Transforms/EarlyCSE/math-1.ll b/llvm/test/Transforms/EarlyCSE/math-1.ll --- a/llvm/test/Transforms/EarlyCSE/math-1.ll +++ b/llvm/test/Transforms/EarlyCSE/math-1.ll @@ -22,7 +22,6 @@ declare double @atan(double) #0 define double @f_atan() { ; CHECK-LABEL: @f_atan( -; CHECK-NEXT: [[RES:%.*]] = tail call fast double @atan(double 1.000000e+00) ; CHECK-NEXT: ret double 0x3FE921FB ; %res = tail call fast double @atan(double 1.0) diff --git a/llvm/test/Transforms/EarlyCSE/math-2.ll b/llvm/test/Transforms/EarlyCSE/math-2.ll --- a/llvm/test/Transforms/EarlyCSE/math-2.ll +++ b/llvm/test/Transforms/EarlyCSE/math-2.ll @@ -4,7 +4,6 @@ declare double @atan2(double, double) #0 define double @f_atan2() { ; CHECK-LABEL: @f_atan2( -; CHECK-NEXT: [[RES:%.*]] = tail call fast double @atan2(double 1.000000e+00, double 2.000000e+00) ; CHECK-NEXT: ret double 0x3FDDAC6{{.+}} ; %res = tail call fast double @atan2(double 1.0, double 2.0)