[llvm] 4e37d00 - ValueTracking: Teach isKnownNeverInfinity about rounding intrinsics

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 20 09:45:13 PST 2022


Author: Matt Arsenault
Date: 2022-12-20T12:45:07-05:00
New Revision: 4e37d00b9dcd88dbe76ad1d3c6d7cb84b8dd28aa

URL: https://github.com/llvm/llvm-project/commit/4e37d00b9dcd88dbe76ad1d3c6d7cb84b8dd28aa
DIFF: https://github.com/llvm/llvm-project/commit/4e37d00b9dcd88dbe76ad1d3c6d7cb84b8dd28aa.diff

LOG: ValueTracking: Teach isKnownNeverInfinity about rounding intrinsics

Added: 
    

Modified: 
    llvm/include/llvm/IR/Type.h
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstSimplify/floating-point-compare.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h
index 6b291ec0c897c..0014d8e6e5081 100644
--- a/llvm/include/llvm/IR/Type.h
+++ b/llvm/include/llvm/IR/Type.h
@@ -187,6 +187,14 @@ class Type {
            getTypeID() == PPC_FP128TyID;
   }
 
+  /// Returns true if this is a floating-point type that is an unevaluated sum
+  /// of multiple floating-point units.
+  /// An example of such a type is ppc_fp128, also known as double-double, which
+  /// consists of two IEEE 754 doubles.
+  bool isMultiUnitFPType() const {
+    return getTypeID() == PPC_FP128TyID;
+  }
+
   const fltSemantics &getFltSemantics() const;
 
   /// Return true if this is X86 MMX.

diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 36fcec9b2e9fc..c25506e5030fd 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3807,7 +3807,21 @@ bool llvm::isKnownNeverInfinity(const Value *V, const TargetLibraryInfo *TLI,
       case Intrinsic::canonicalize:
       case Intrinsic::copysign:
       case Intrinsic::arithmetic_fence:
+      case Intrinsic::trunc:
         return isKnownNeverInfinity(Inst->getOperand(0), TLI, Depth + 1);
+      case Intrinsic::floor:
+      case Intrinsic::ceil:
+      case Intrinsic::rint:
+      case Intrinsic::nearbyint:
+      case Intrinsic::round:
+      case Intrinsic::roundeven:
+        // PPC_FP128 is a special case.
+        if (V->getType()->isMultiUnitFPType())
+          return false;
+        return isKnownNeverInfinity(Inst->getOperand(0), TLI, Depth + 1);
+      case Intrinsic::fptrunc_round:
+        // Requires knowing the value range.
+        return false;
       default:
         break;
       }

diff  --git a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
index 7a5568408c33c..ff346bc203454 100644
--- a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
+++ b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
@@ -1373,10 +1373,7 @@ declare double @llvm.arithmetic.fence.f64(double)
 
 define i1 @isKnownNeverInfinity_floor(double %x) {
 ; CHECK-LABEL: @isKnownNeverInfinity_floor(
-; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X:%.*]], 1.000000e+00
-; CHECK-NEXT:    [[E:%.*]] = call double @llvm.floor.f64(double [[A]])
-; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %a = fadd ninf double %x, 1.0
   %e = call double @llvm.floor.f64(double %a)
@@ -1399,10 +1396,7 @@ declare double @llvm.floor.f64(double)
 
 define i1 @isKnownNeverInfinity_ceil(double %x) {
 ; CHECK-LABEL: @isKnownNeverInfinity_ceil(
-; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X:%.*]], 1.000000e+00
-; CHECK-NEXT:    [[E:%.*]] = call double @llvm.ceil.f64(double [[A]])
-; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %a = fadd ninf double %x, 1.0
   %e = call double @llvm.ceil.f64(double %a)
@@ -1425,10 +1419,7 @@ declare double @llvm.ceil.f64(double)
 
 define i1 @isKnownNeverInfinity_trunc(double %x) {
 ; CHECK-LABEL: @isKnownNeverInfinity_trunc(
-; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X:%.*]], 1.000000e+00
-; CHECK-NEXT:    [[E:%.*]] = call double @llvm.trunc.f64(double [[A]])
-; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %a = fadd ninf double %x, 1.0
   %e = call double @llvm.trunc.f64(double %a)
@@ -1451,10 +1442,7 @@ declare double @llvm.trunc.f64(double)
 
 define i1 @isKnownNeverInfinity_rint(double %x) {
 ; CHECK-LABEL: @isKnownNeverInfinity_rint(
-; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X:%.*]], 1.000000e+00
-; CHECK-NEXT:    [[E:%.*]] = call double @llvm.rint.f64(double [[A]])
-; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %a = fadd ninf double %x, 1.0
   %e = call double @llvm.rint.f64(double %a)
@@ -1477,10 +1465,7 @@ declare double @llvm.rint.f64(double)
 
 define i1 @isKnownNeverInfinity_nearbyint(double %x) {
 ; CHECK-LABEL: @isKnownNeverInfinity_nearbyint(
-; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X:%.*]], 1.000000e+00
-; CHECK-NEXT:    [[E:%.*]] = call double @llvm.nearbyint.f64(double [[A]])
-; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %a = fadd ninf double %x, 1.0
   %e = call double @llvm.nearbyint.f64(double %a)
@@ -1503,10 +1488,7 @@ declare double @llvm.nearbyint.f64(double)
 
 define i1 @isKnownNeverInfinity_round(double %x) {
 ; CHECK-LABEL: @isKnownNeverInfinity_round(
-; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X:%.*]], 1.000000e+00
-; CHECK-NEXT:    [[E:%.*]] = call double @llvm.round.f64(double [[A]])
-; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %a = fadd ninf double %x, 1.0
   %e = call double @llvm.round.f64(double %a)
@@ -1529,10 +1511,7 @@ declare double @llvm.round.f64(double)
 
 define i1 @isKnownNeverInfinity_roundeven(double %x) {
 ; CHECK-LABEL: @isKnownNeverInfinity_roundeven(
-; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X:%.*]], 1.000000e+00
-; CHECK-NEXT:    [[E:%.*]] = call double @llvm.roundeven.f64(double [[A]])
-; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %a = fadd ninf double %x, 1.0
   %e = call double @llvm.roundeven.f64(double %a)
@@ -1567,3 +1546,117 @@ define i1 @isNotKnownNeverInfinity_fptrunc_round(double %x) {
 }
 
 declare float @llvm.fptrunc.round.f32.f64(double, metadata)
+
+declare ppc_fp128 @llvm.floor.ppcf128(ppc_fp128)
+
+define i1 @isKnownNeverInfinity_floor_ppcf128(ppc_fp128 %x) {
+; CHECK-LABEL: @isKnownNeverInfinity_floor_ppcf128(
+; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X:%.*]], [[X]]
+; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.floor.ppcf128(ppc_fp128 [[A]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = fadd ninf ppc_fp128 %x, %x
+  %e = call ppc_fp128 @llvm.floor.ppcf128(ppc_fp128 %a)
+  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
+  ret i1 %r
+}
+
+declare ppc_fp128 @llvm.ceil.ppcf128(ppc_fp128)
+
+define i1 @isKnownNeverInfinity_ceil_ppcf128(ppc_fp128 %x) {
+; CHECK-LABEL: @isKnownNeverInfinity_ceil_ppcf128(
+; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X:%.*]], [[X]]
+; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.ceil.ppcf128(ppc_fp128 [[A]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = fadd ninf ppc_fp128 %x, %x
+  %e = call ppc_fp128 @llvm.ceil.ppcf128(ppc_fp128 %a)
+  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
+  ret i1 %r
+}
+
+declare ppc_fp128 @llvm.rint.ppcf128(ppc_fp128)
+
+define i1 @isKnownNeverInfinity_rint_ppcf128(ppc_fp128 %x) {
+; CHECK-LABEL: @isKnownNeverInfinity_rint_ppcf128(
+; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X:%.*]], [[X]]
+; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.rint.ppcf128(ppc_fp128 [[A]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = fadd ninf ppc_fp128 %x, %x
+  %e = call ppc_fp128 @llvm.rint.ppcf128(ppc_fp128 %a)
+  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
+  ret i1 %r
+}
+
+declare ppc_fp128 @llvm.nearbyint.ppcf128(ppc_fp128)
+
+define i1 @isKnownNeverInfinity_nearbyint_ppcf128(ppc_fp128 %x) {
+; CHECK-LABEL: @isKnownNeverInfinity_nearbyint_ppcf128(
+; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X:%.*]], [[X]]
+; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.nearbyint.ppcf128(ppc_fp128 [[A]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = fadd ninf ppc_fp128 %x, %x
+  %e = call ppc_fp128 @llvm.nearbyint.ppcf128(ppc_fp128 %a)
+  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
+  ret i1 %r
+}
+
+declare ppc_fp128 @llvm.round.ppcf128(ppc_fp128)
+
+define i1 @isKnownNeverInfinity_round_ppcf128(ppc_fp128 %x) {
+; CHECK-LABEL: @isKnownNeverInfinity_round_ppcf128(
+; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X:%.*]], [[X]]
+; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.round.ppcf128(ppc_fp128 [[A]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = fadd ninf ppc_fp128 %x, %x
+  %e = call ppc_fp128 @llvm.round.ppcf128(ppc_fp128 %a)
+  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
+  ret i1 %r
+}
+
+declare ppc_fp128 @llvm.roundeven.ppcf128(ppc_fp128)
+
+define i1 @isKnownNeverInfinity_roundeven_ppcf128(ppc_fp128 %x) {
+; CHECK-LABEL: @isKnownNeverInfinity_roundeven_ppcf128(
+; CHECK-NEXT:    [[A:%.*]] = fadd ninf ppc_fp128 [[X:%.*]], [[X]]
+; CHECK-NEXT:    [[E:%.*]] = call ppc_fp128 @llvm.roundeven.ppcf128(ppc_fp128 [[A]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une ppc_fp128 [[E]], 0xM7FF00000000000000000000000000000
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = fadd ninf ppc_fp128 %x, %x
+  %e = call ppc_fp128 @llvm.roundeven.ppcf128(ppc_fp128 %a)
+  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
+  ret i1 %r
+}
+
+declare ppc_fp128 @llvm.trunc.ppcf128(ppc_fp128)
+
+define i1 @isKnownNeverInfinity_trunc_ppcf128(ppc_fp128 %x) {
+; CHECK-LABEL: @isKnownNeverInfinity_trunc_ppcf128(
+; CHECK-NEXT:    ret i1 true
+;
+  %a = fadd ninf ppc_fp128 %x, %x
+  %e = call ppc_fp128 @llvm.trunc.ppcf128(ppc_fp128 %a)
+  %r = fcmp une ppc_fp128 %e, 0xM7FF00000000000000000000000000000
+  ret i1 %r
+}
+
+declare x86_fp80 @llvm.ceil.f80(x86_fp80)
+
+define i1 @isKnownNeverInfinity_ceil_x86_fp80(x86_fp80 %x) {
+; CHECK-LABEL: @isKnownNeverInfinity_ceil_x86_fp80(
+; CHECK-NEXT:    ret i1 true
+;
+  %a = fadd ninf x86_fp80 %x, %x
+  %e = call x86_fp80 @llvm.ceil.f80(x86_fp80 %a)
+  %r = fcmp une x86_fp80 %e, 0xK7FFF8000000000000000
+  ret i1 %r
+}


        


More information about the llvm-commits mailing list