[llvm] [InstSimplify] Fold expression using basic properties of floor and ceiling function (PR #107107)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 3 06:34:12 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: None (c8ef)

<details>
<summary>Changes</summary>

alive2: https://alive2.llvm.org/ce/z/giSGaj

---
Full diff: https://github.com/llvm/llvm-project/pull/107107.diff


2 Files Affected:

- (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+33-5) 
- (added) llvm/test/Transforms/InstSimplify/fp-floor-ceil.ll (+114) 


``````````diff
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 32a9f1ab34fb3f..e67a2875733416 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4130,12 +4130,9 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
   //
   // This catches the 2 variable input case, constants are handled below as a
   // class-like compare.
+  KnownFPClass LHSClass = computeKnownFPClass(LHS, fcAllFlags, /*Depth=*/0, Q);
+  KnownFPClass RHSClass = computeKnownFPClass(RHS, fcAllFlags, /*Depth=*/0, Q);
   if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO) {
-    KnownFPClass RHSClass =
-        computeKnownFPClass(RHS, fcAllFlags, /*Depth=*/0, Q);
-    KnownFPClass LHSClass =
-        computeKnownFPClass(LHS, fcAllFlags, /*Depth=*/0, Q);
-
     if (FMF.noNaNs() ||
         (RHSClass.isKnownNeverNaN() && LHSClass.isKnownNeverNaN()))
       return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD);
@@ -4143,6 +4140,37 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
     if (RHSClass.isKnownAlwaysNaN() || LHSClass.isKnownAlwaysNaN())
       return ConstantInt::get(RetTy, Pred == CmpInst::FCMP_UNO);
   }
+  // floor(x) <= x --> true; x <= ceil(x) --> true
+  if (LHSClass.isKnownNeverNaN() &&
+          match(LHS, m_Intrinsic<Intrinsic::floor>(m_Specific(RHS))) ||
+      RHSClass.isKnownNeverNaN() &&
+          match(RHS, m_Intrinsic<Intrinsic::ceil>(m_Specific(LHS)))) {
+    switch (Pred) {
+    case FCmpInst::FCMP_OLE:
+    case FCmpInst::FCMP_ULE:
+      return getTrue(RetTy);
+    case FCmpInst::FCMP_OGT:
+    case FCmpInst::FCMP_UGT:
+      return getFalse(RetTy);
+    default:
+      break;
+    }
+  }
+  if (RHSClass.isKnownNeverNaN() &&
+          match(RHS, m_Intrinsic<Intrinsic::floor>(m_Specific(LHS))) ||
+      LHSClass.isKnownNeverNaN() &&
+          match(LHS, m_Intrinsic<Intrinsic::ceil>(m_Specific(RHS)))) {
+    switch (Pred) {
+    case FCmpInst::FCMP_OGE:
+    case FCmpInst::FCMP_UGE:
+      return getTrue(RetTy);
+    case FCmpInst::FCMP_OLT:
+    case FCmpInst::FCMP_ULT:
+      return getFalse(RetTy);
+    default:
+      break;
+    }
+  }
 
   const APFloat *C = nullptr;
   match(RHS, m_APFloatAllowPoison(C));
diff --git a/llvm/test/Transforms/InstSimplify/fp-floor-ceil.ll b/llvm/test/Transforms/InstSimplify/fp-floor-ceil.ll
new file mode 100644
index 00000000000000..fe78656b014ae0
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/fp-floor-ceil.ll
@@ -0,0 +1,114 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
+
+define i1 @x_floor_ole(float %0) {
+; CHECK-LABEL: @x_floor_ole(
+; CHECK-NEXT:    ret i1 true
+;
+  %2 = call nnan float @llvm.floor.f32(float %0)
+  %3 = fcmp ole float %2, %0
+  ret i1 %3
+}
+
+define i1 @x_floor_ule(float %0) {
+; CHECK-LABEL: @x_floor_ule(
+; CHECK-NEXT:    ret i1 true
+;
+  %2 = call nnan float @llvm.floor.f32(float %0)
+  %3 = fcmp ule float %2, %0
+  ret i1 %3
+}
+
+define i1 @x_floor_ogt(float %0) {
+; CHECK-LABEL: @x_floor_ogt(
+; CHECK-NEXT:    ret i1 false
+;
+  %2 = call nnan float @llvm.floor.f32(float %0)
+  %3 = fcmp ogt float %2, %0
+  ret i1 %3
+}
+
+define i1 @x_floor_ugt(float %0) {
+; CHECK-LABEL: @x_floor_ugt(
+; CHECK-NEXT:    ret i1 false
+;
+  %2 = call nnan float @llvm.floor.f32(float %0)
+  %3 = fcmp ugt float %2, %0
+  ret i1 %3
+}
+
+define i1 @x_floor_ueq(float %0) {
+; CHECK-LABEL: @x_floor_ueq(
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan float @llvm.floor.f32(float [[TMP0:%.*]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp ueq float [[TMP2]], [[TMP0]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %2 = call nnan float @llvm.floor.f32(float %0)
+  %3 = fcmp ueq float %2, %0
+  ret i1 %3
+}
+
+define <2 x i1> @x_floor_ugt_vec(<2 x float> %0) {
+; CHECK-LABEL: @x_floor_ugt_vec(
+; CHECK-NEXT:    ret <2 x i1> zeroinitializer
+;
+  %2 = call nnan <2 x float> @llvm.floor.v2f32(<2 x float> %0)
+  %3 = fcmp ugt <2 x float> %2, %0
+  ret <2 x i1> %3
+}
+
+define i1 @x_ceil_ole(float %0) {
+; CHECK-LABEL: @x_ceil_ole(
+; CHECK-NEXT:    ret i1 false
+;
+  %2 = call nnan float @llvm.ceil.f32(float %0)
+  %3 = fcmp olt float %2, %0
+  ret i1 %3
+}
+
+define i1 @x_ceil_ule(float %0) {
+; CHECK-LABEL: @x_ceil_ule(
+; CHECK-NEXT:    ret i1 false
+;
+  %2 = call nnan float @llvm.ceil.f32(float %0)
+  %3 = fcmp ult float %2, %0
+  ret i1 %3
+}
+
+define i1 @x_ceil_ogt(float %0) {
+; CHECK-LABEL: @x_ceil_ogt(
+; CHECK-NEXT:    ret i1 true
+;
+  %2 = call nnan float @llvm.ceil.f32(float %0)
+  %3 = fcmp oge float %2, %0
+  ret i1 %3
+}
+
+define i1 @x_ceil_ugt(float %0) {
+; CHECK-LABEL: @x_ceil_ugt(
+; CHECK-NEXT:    ret i1 true
+;
+  %2 = call nnan float @llvm.ceil.f32(float %0)
+  %3 = fcmp uge float %2, %0
+  ret i1 %3
+}
+
+define i1 @x_ceil_ueq(float %0) {
+; CHECK-LABEL: @x_ceil_ueq(
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan float @llvm.ceil.f32(float [[TMP0:%.*]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp ueq float [[TMP2]], [[TMP0]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %2 = call nnan float @llvm.ceil.f32(float %0)
+  %3 = fcmp ueq float %2, %0
+  ret i1 %3
+}
+
+define <2 x i1> @x_ceil_ugt_vec(<2 x float> %0) {
+; CHECK-LABEL: @x_ceil_ugt_vec(
+; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
+;
+  %2 = call nnan <2 x float> @llvm.ceil.f32(<2 x float> %0)
+  %3 = fcmp uge <2 x float> %2, %0
+  ret <2 x i1> %3
+}

``````````

</details>


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


More information about the llvm-commits mailing list