[llvm] [KnownFPClass] Add sign preserving deductions to `atan2(y, x)` (PR #223176)

via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 12 14:32:47 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-globalisel

Author: Eric Ross (ZERICO2005)

<details>
<summary>Changes</summary>

`atan2(y, x)` should return the same sign as `y` (up to the denormal mode):
- If `y >= +0.0`, then `atan2(y, x) >= +0.0`
- If `y <= -0.0`, then `atan2(y, x) <= -0.0`

AI Disclosure:
I used ChatGPT Codex (5.6 sol) to help write the tests.


---

Patch is 40.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/223176.diff


6 Files Affected:

- (modified) llvm/lib/Analysis/ValueTracking.cpp (+8) 
- (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+8) 
- (modified) llvm/lib/Support/KnownFPClass.cpp (+18-2) 
- (modified) llvm/test/Transforms/Attributor/nofpclass-atan2.ll (+428-30) 
- (modified) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-atan2.ll (+25) 
- (modified) llvm/unittests/CodeGen/GlobalISel/KnownFPClassTest.cpp (+3-3) 


``````````diff
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 1580571a01451..f0e86a3bf9905 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5503,6 +5503,14 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
       FPClassTest InterestedY = InterestedClasses;
       FPClassTest InterestedX = InterestedClasses;
 
+      // We can rule out negative values if y cannot have a negative value.
+      if ((InterestedClasses & fcNegFinite) != fcNone)
+        InterestedY |= fcNegative;
+
+      // We can rule out positive values if y cannot have a positive value.
+      if ((InterestedClasses & fcPosFinite) != fcNone)
+        InterestedY |= fcPositive | fcNegSubnormal;
+
       // We can rule out zero and subnormal if x cannot have a positive value.
       if ((InterestedClasses & (fcZero | fcSubnormal)) != fcNone)
         InterestedX |= fcPositive | fcNegSubnormal;
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 0bbafeb6dca41..ad07e0055fc7a 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -1406,6 +1406,14 @@ void GISelValueTracking::computeKnownFPClass(Register R,
     FPClassTest InterestedY = InterestedClasses;
     FPClassTest InterestedX = InterestedClasses;
 
+    // We can rule out negative values if y cannot have a negative value.
+    if ((InterestedClasses & fcNegFinite) != fcNone)
+      InterestedY |= fcNegative;
+
+    // We can rule out positive values if y cannot have a positive value.
+    if ((InterestedClasses & fcPosFinite) != fcNone)
+      InterestedY |= fcPositive | fcNegSubnormal;
+
     // We can rule out zero and subnormal if x cannot have a positive value.
     if ((InterestedClasses & (fcZero | fcSubnormal)) != fcNone)
       InterestedX |= fcPositive | fcNegSubnormal;
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 75636ffc73361..930d91be93045 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -798,13 +798,29 @@ KnownFPClass KnownFPClass::atan2(const KnownFPClass &KnownY,
   Known.propagateNonNaN(KnownY, KnownX);
 
   // Negative subnormals could be treated like positive zero.
-  const bool XCannotHavePositiveValue = KnownX.isKnownNever(fcPositive) &&
+  const bool XCannotHavePositiveInput = KnownX.isKnownNever(fcPositive) &&
                                         KnownX.isKnownNeverLogicalPosZero(Mode);
+  const bool YCannotHavePositiveInput = KnownY.isKnownNever(fcPositive) &&
+                                        KnownY.isKnownNeverLogicalPosZero(Mode);
 
   // If x <= -0.0, then |atan2(y, x)| >= pi/2
-  if (XCannotHavePositiveValue)
+  if (XCannotHavePositiveInput)
     Known.knownNot(fcZero | fcSubnormal);
 
+  // If y >= +0.0, then atan2(y, x) >= +0.0
+  if (KnownY.isKnownNever(fcNegative))
+    Known.knownNot(fcNegative);
+
+  // If y <= -0.0, then atan2(y, x) <= -0.0
+  // We do this deduction last in case we were able to rule out a negative
+  // subnormal result earlier.
+  if (YCannotHavePositiveInput) {
+    Known.knownNot(fcPosSubnormal | fcPosNormal | fcPosInf);
+    // Negative subnormal results can flush to +0.0.
+    if (Known.isKnownNever(fcNegSubnormal) || !Mode.outputsMayBePositiveZero())
+      Known.knownNot(fcPosZero);
+  }
+
   return Known;
 }
 
diff --git a/llvm/test/Transforms/Attributor/nofpclass-atan2.ll b/llvm/test/Transforms/Attributor/nofpclass-atan2.ll
index feb4a7075b435..ae0e7c6f34ea2 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-atan2.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-atan2.ll
@@ -7,7 +7,7 @@ declare float @llvm.atan2.f32(float, float)
 define float @ret_atan2(float %arg0, float %arg1) {
 ; CHECK-LABEL: define nofpclass(inf) float @ret_atan2(
 ; CHECK-SAME: float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf) float @llvm.atan2.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR6:[0-9]+]]
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf) float @llvm.atan2.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR10:[0-9]+]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = call float @llvm.atan2.f32(float %arg0, float %arg1)
@@ -17,7 +17,7 @@ define float @ret_atan2(float %arg0, float %arg1) {
 define float @ret_atan2_nonan(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {
 ; CHECK-LABEL: define nofpclass(nan inf) float @ret_atan2_nonan(
 ; CHECK-SAME: float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf) float @llvm.atan2.f32(float nofpclass(nan) [[ARG0]], float nofpclass(nan) [[ARG1]]) #[[ATTR6]]
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf) float @llvm.atan2.f32(float nofpclass(nan) [[ARG0]], float nofpclass(nan) [[ARG1]]) #[[ATTR10]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = call float @llvm.atan2.f32(float %arg0, float %arg1)
@@ -27,18 +27,180 @@ define float @ret_atan2_nonan(float nofpclass(nan) %arg0, float nofpclass(nan) %
 define float @ret_atan2_nosnan(float nofpclass(snan) %arg0, float nofpclass(snan) %arg1) {
 ; CHECK-LABEL: define nofpclass(snan inf) float @ret_atan2_nosnan(
 ; CHECK-SAME: float nofpclass(snan) [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(snan inf) float @llvm.atan2.f32(float nofpclass(snan) [[ARG0]], float nofpclass(snan) [[ARG1]]) #[[ATTR6]]
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(snan inf) float @llvm.atan2.f32(float nofpclass(snan) [[ARG0]], float nofpclass(snan) [[ARG1]]) #[[ATTR10]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = call float @llvm.atan2.f32(float %arg0, float %arg1)
   ret float %call
 }
 
+; Quadrant tests
+
+define float @ret_atan2_normal_quad_1(float nofpclass(nan inf zero sub nnorm) %y, float nofpclass(nan inf zero sub nnorm) %x) {
+; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @ret_atan2_normal_quad_1(
+; CHECK-SAME: float nofpclass(nan inf zero sub nnorm) [[Y:%.*]], float nofpclass(nan inf zero sub nnorm) [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf nzero nsub nnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero sub nnorm) [[Y]], float nofpclass(nan inf zero sub nnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_quad_2(float nofpclass(nan inf zero sub nnorm) %y, float nofpclass(nan inf zero sub pnorm) %x) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @ret_atan2_normal_quad_2(
+; CHECK-SAME: float nofpclass(nan inf zero sub nnorm) [[Y:%.*]], float nofpclass(nan inf zero sub pnorm) [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf zero sub nnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero sub nnorm) [[Y]], float nofpclass(nan inf zero sub pnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_quad_3(float nofpclass(nan inf zero sub pnorm) %y, float nofpclass(nan inf zero sub pnorm) %x) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub pnorm) float @ret_atan2_normal_quad_3(
+; CHECK-SAME: float nofpclass(nan inf zero sub pnorm) [[Y:%.*]], float nofpclass(nan inf zero sub pnorm) [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf zero sub pnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero sub pnorm) [[Y]], float nofpclass(nan inf zero sub pnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_quad_4(float nofpclass(nan inf zero sub pnorm) %y, float nofpclass(nan inf zero sub nnorm) %x) {
+; CHECK-LABEL: define nofpclass(nan inf pzero psub pnorm) float @ret_atan2_normal_quad_4(
+; CHECK-SAME: float nofpclass(nan inf zero sub pnorm) [[Y:%.*]], float nofpclass(nan inf zero sub nnorm) [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf pzero psub pnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero sub pnorm) [[Y]], float nofpclass(nan inf zero sub nnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_1(float nofpclass(nan inf zero nsub nnorm) %y, float nofpclass(nan inf zero nsub nnorm) %x) {
+; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @ret_atan2_normal_subnormal_quad_1(
+; CHECK-SAME: float nofpclass(nan inf zero nsub nnorm) [[Y:%.*]], float nofpclass(nan inf zero nsub nnorm) [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf nzero nsub nnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero nsub nnorm) [[Y]], float nofpclass(nan inf zero nsub nnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_2(float nofpclass(nan inf zero nsub nnorm) %y, float nofpclass(nan inf zero psub pnorm) %x) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @ret_atan2_normal_subnormal_quad_2(
+; CHECK-SAME: float nofpclass(nan inf zero nsub nnorm) [[Y:%.*]], float nofpclass(nan inf zero psub pnorm) [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf zero sub nnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero nsub nnorm) [[Y]], float nofpclass(nan inf zero psub pnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_3(float nofpclass(nan inf zero psub pnorm) %y, float nofpclass(nan inf zero psub pnorm) %x) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub pnorm) float @ret_atan2_normal_subnormal_quad_3(
+; CHECK-SAME: float nofpclass(nan inf zero psub pnorm) [[Y:%.*]], float nofpclass(nan inf zero psub pnorm) [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf zero sub pnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero psub pnorm) [[Y]], float nofpclass(nan inf zero psub pnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_4(float nofpclass(nan inf zero psub pnorm) %y, float nofpclass(nan inf zero nsub nnorm) %x) {
+; CHECK-LABEL: define nofpclass(nan inf pzero psub pnorm) float @ret_atan2_normal_subnormal_quad_4(
+; CHECK-SAME: float nofpclass(nan inf zero psub pnorm) [[Y:%.*]], float nofpclass(nan inf zero nsub nnorm) [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf pzero psub pnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero psub pnorm) [[Y]], float nofpclass(nan inf zero nsub nnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_1_mode_dynamic_dynamic(float nofpclass(nan inf zero nsub nnorm) %y, float nofpclass(nan inf zero nsub nnorm) %x) denormal_fpenv(float: dynamic|dynamic) {
+; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @ret_atan2_normal_subnormal_quad_1_mode_dynamic_dynamic(
+; CHECK-SAME: float nofpclass(nan inf zero nsub nnorm) [[Y:%.*]], float nofpclass(nan inf zero nsub nnorm) [[X:%.*]]) #[[ATTR2:[0-9]+]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf nzero nsub nnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero nsub nnorm) [[Y]], float nofpclass(nan inf zero nsub nnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_2_mode_dynamic_dynamic(float nofpclass(nan inf zero nsub nnorm) %y, float nofpclass(nan inf zero psub pnorm) %x) denormal_fpenv(float: dynamic|dynamic) {
+; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @ret_atan2_normal_subnormal_quad_2_mode_dynamic_dynamic(
+; CHECK-SAME: float nofpclass(nan inf zero nsub nnorm) [[Y:%.*]], float nofpclass(nan inf zero psub pnorm) [[X:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf nzero nsub nnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero nsub nnorm) [[Y]], float nofpclass(nan inf zero psub pnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_3_mode_dynamic_dynamic(float nofpclass(nan inf zero psub pnorm) %y, float nofpclass(nan inf zero psub pnorm) %x) denormal_fpenv(float: dynamic|dynamic) {
+; CHECK-LABEL: define nofpclass(nan inf) float @ret_atan2_normal_subnormal_quad_3_mode_dynamic_dynamic(
+; CHECK-SAME: float nofpclass(nan inf zero psub pnorm) [[Y:%.*]], float nofpclass(nan inf zero psub pnorm) [[X:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf) float @llvm.atan2.f32(float nofpclass(nan inf zero psub pnorm) [[Y]], float nofpclass(nan inf zero psub pnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_4_mode_dynamic_dynamic(float nofpclass(nan inf zero psub pnorm) %y, float nofpclass(nan inf zero nsub nnorm) %x) denormal_fpenv(float: dynamic|dynamic) {
+; CHECK-LABEL: define nofpclass(nan inf) float @ret_atan2_normal_subnormal_quad_4_mode_dynamic_dynamic(
+; CHECK-SAME: float nofpclass(nan inf zero psub pnorm) [[Y:%.*]], float nofpclass(nan inf zero nsub nnorm) [[X:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf) float @llvm.atan2.f32(float nofpclass(nan inf zero psub pnorm) [[Y]], float nofpclass(nan inf zero nsub nnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_1_mode_ftpz_dapz(float nofpclass(nan inf zero nsub nnorm) %y, float nofpclass(nan inf zero nsub nnorm) %x) denormal_fpenv(float: positivezero|positivezero) {
+; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @ret_atan2_normal_subnormal_quad_1_mode_ftpz_dapz(
+; CHECK-SAME: float nofpclass(nan inf zero nsub nnorm) [[Y:%.*]], float nofpclass(nan inf zero nsub nnorm) [[X:%.*]]) #[[ATTR3:[0-9]+]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf nzero nsub nnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero nsub nnorm) [[Y]], float nofpclass(nan inf zero nsub nnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_2_mode_ftpz_dapz(float nofpclass(nan inf zero nsub nnorm) %y, float nofpclass(nan inf zero psub pnorm) %x) denormal_fpenv(float: positivezero|positivezero) {
+; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @ret_atan2_normal_subnormal_quad_2_mode_ftpz_dapz(
+; CHECK-SAME: float nofpclass(nan inf zero nsub nnorm) [[Y:%.*]], float nofpclass(nan inf zero psub pnorm) [[X:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf nzero nsub nnorm) float @llvm.atan2.f32(float nofpclass(nan inf zero nsub nnorm) [[Y]], float nofpclass(nan inf zero psub pnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_3_mode_ftpz_dapz(float nofpclass(nan inf zero psub pnorm) %y, float nofpclass(nan inf zero psub pnorm) %x) denormal_fpenv(float: positivezero|positivezero) {
+; CHECK-LABEL: define nofpclass(nan inf) float @ret_atan2_normal_subnormal_quad_3_mode_ftpz_dapz(
+; CHECK-SAME: float nofpclass(nan inf zero psub pnorm) [[Y:%.*]], float nofpclass(nan inf zero psub pnorm) [[X:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf) float @llvm.atan2.f32(float nofpclass(nan inf zero psub pnorm) [[Y]], float nofpclass(nan inf zero psub pnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
+define float @ret_atan2_normal_subnormal_quad_4_mode_ftpz_dapz(float nofpclass(nan inf zero psub pnorm) %y, float nofpclass(nan inf zero nsub nnorm) %x) denormal_fpenv(float: positivezero|positivezero) {
+; CHECK-LABEL: define nofpclass(nan inf) float @ret_atan2_normal_subnormal_quad_4_mode_ftpz_dapz(
+; CHECK-SAME: float nofpclass(nan inf zero psub pnorm) [[Y:%.*]], float nofpclass(nan inf zero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan inf) float @llvm.atan2.f32(float nofpclass(nan inf zero psub pnorm) [[Y]], float nofpclass(nan inf zero nsub nnorm) [[X]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.atan2.f32(float %y, float %x)
+  ret float %call
+}
+
 ; |atan2(y, x)| >= pi/2 when x is a negative normal or negative infinity.
-define float @ret_atan2_neg_normal_x(float %y, float nofpclass(nan pinf zero sub pnorm) %x) {
-; CHECK-LABEL: define nofpclass(inf zero sub) float @ret_atan2_neg_normal_x(
+define float @ret_atan2_negnormal_neginf_x(float %y, float nofpclass(nan pinf zero sub pnorm) %x) {
+; CHECK-LABEL: define nofpclass(inf zero sub) float @ret_atan2_negnormal_neginf_x(
 ; CHECK-SAME: float [[Y:%.*]], float nofpclass(nan pinf zero sub pnorm) [[X:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf zero sub) float @llvm.atan2.f32(float [[Y]], float nofpclass(nan pinf zero sub pnorm) [[X]]) #[[ATTR6]]
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf zero sub) float @llvm.atan2.f32(float [[Y]], float nofpclass(nan pinf zero sub pnorm) [[X]]) #[[ATTR10]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = call float @llvm.atan2.f32(float %y, float %x)
@@ -49,50 +211,286 @@ define float @ret_atan2_neg_normal_x(float %y, float nofpclass(nan pinf zero sub
 ; be zero or subnormal. However, a negative subnormal may be treated as a
 ; logical positive zero depending on how the floating point environment handles
 ; denormals. Here we make sure to test every input denormal-mode combination.
-define float @ret_atan2_neg_subnormal_x_ieee_ieee(
-; CHECK-LABEL: define nofpclass(inf zero sub) float @ret_atan2_neg_subnormal_x_ieee_ieee(
-; CHECK-SAME: float [[Y:%.*]], float nofpclass(nan inf zero psub norm) [[X:%.*]]) #[[ATTR2:[0-9]+]] {
-; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf zero sub) float @llvm.atan2.f32(float [[Y]], float nofpclass(nan inf zero psub norm) [[X]]) #[[ATTR6]]
+define float @ret_atan2_negsubnormal_x_mode_ieee_ieee(float %y, float nofpclass(nan inf zero psub norm) %x) denormal_fpenv(float: ieee|ieee) {
+; CHECK-LABEL: define nofpclass(inf zero sub) float @ret_atan2_negsubnormal_x_mode_ieee_ieee(
+; CHECK-SAME: float [[Y:%.*]], float nofpclass(nan inf zero psub norm) [[X:%.*]]) #[[ATTR4:[0-9]+]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf zero sub) float @llvm.atan2.f32(float [[Y]], float nofpclass(nan inf zero psub norm) [[X]]) #[[ATTR10]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
-  float %y, float nofpclass(nan inf zero norm psub) %x)
-  denormal_fpenv(float: ieee|ieee) {
   %call = call float @llvm.atan2.f32(float %y, float %x)
   ret float %call
 }
 
-define float @ret_atan2_neg_subnormal_x_ieee_preservesign(
-; CHECK-LABEL: define nofpclass(inf zero sub) float @ret_atan2_neg_subnormal_x_ieee_preservesign(
-; CHECK-SAME: float [[Y:%.*]], float nofpclass(nan inf zero psub norm) [[X:%.*]]) #[[ATTR3:[0-9]+]] {
-; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf zero sub) float @llvm.atan2.f32(float [[Y]], float nofpclass(nan inf zero psub norm) [[X]]) #[[ATTR6]]
+define float @ret_atan2_negsubnormal_x_mode_ieee_daz(float %y, float nofpclass(nan inf zero psub norm) %x) denormal_fpenv(float: ieee|preservesign) {
+; CHECK-LABEL...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/223176


More information about the llvm-commits mailing list