[PATCH] D124150: [InstCombine] Handle predicates for fold fcmp-of-copysign

Chenbing.Zheng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 21 23:52:26 PDT 2022


Chenbing.Zheng updated this revision to Diff 424388.
Chenbing.Zheng retitled this revision from "[InstCombine] Handle more predicates for fold fcmp-of-copysign " to "[InstCombine] Handle predicates for fold fcmp-of-copysign ".
Chenbing.Zheng edited the summary of this revision.
Chenbing.Zheng added a comment.

address comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D124150/new/

https://reviews.llvm.org/D124150

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
  llvm/test/Transforms/InstCombine/fcmp.ll


Index: llvm/test/Transforms/InstCombine/fcmp.ll
===================================================================
--- llvm/test/Transforms/InstCombine/fcmp.ll
+++ llvm/test/Transforms/InstCombine/fcmp.ll
@@ -605,12 +605,10 @@
   ret <2 x i1> %r
 }
 
-; TODO: Handle different predicates.
-
 define i1 @is_signbit_clear(double %x) {
 ; CHECK-LABEL: @is_signbit_clear(
-; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
+; CHECK-NEXT:    [[R:%.*]] = icmp sgt i64 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %s = call double @llvm.copysign.f64(double -42.0, double %x)
@@ -618,6 +616,28 @@
   ret i1 %r
 }
 
+define i1 @is_signbit_clear_1(double %x) {
+; CHECK-LABEL: @is_signbit_clear_1(
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
+; CHECK-NEXT:    [[R:%.*]] = icmp slt i64 [[TMP1]], 1
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %s = call double @llvm.copysign.f64(double -42.0, double %x)
+  %r = fcmp ule double %s, 0.0
+  ret i1 %r
+}
+
+define i1 @is_signbit_clear_2(double %x) {
+; CHECK-LABEL: @is_signbit_clear_2(
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
+; CHECK-NEXT:    [[R:%.*]] = icmp sgt i64 [[TMP1]], -1
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %s = call double @llvm.copysign.f64(double -42.0, double %x)
+  %r = fcmp uge double %s, 0.0
+  ret i1 %r
+}
+
 ; Negative test - uses
 
 define i1 @is_signbit_set_extra_use(double %x, double* %p) {
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -6749,7 +6749,6 @@
   // Convert a sign-bit test of an FP value into a cast and integer compare.
   // TODO: Simplify if the copysign constant is 0.0 or NaN.
   // TODO: Handle non-zero compare constants.
-  // TODO: Handle other predicates.
   const APFloat *C;
   if (match(Op0, m_OneUse(m_Intrinsic<Intrinsic::copysign>(m_APFloat(C),
                                                            m_Value(X)))) &&
@@ -6758,10 +6757,28 @@
     if (auto *VecTy = dyn_cast<VectorType>(OpType))
       IntType = VectorType::get(IntType, VecTy->getElementCount());
 
-    // copysign(non-zero constant, X) < 0.0 --> (bitcast X) < 0
-    if (Pred == FCmpInst::FCMP_OLT) {
-      Value *IntX = Builder.CreateBitCast(X, IntType);
-      return new ICmpInst(ICmpInst::ICMP_SLT, IntX,
+    // copysign(non-zero constant, X) <  0.0 --> (bitcast X) <  0
+    // copysign(non-zero constant, X) >  0.0 --> (bitcast X) >  0
+    // copysign(non-zero constant, X) <= 0.0 --> (bitcast X) <= 0
+    // copysign(non-zero constant, X) >= 0.0 --> (bitcast X) >= 0
+    switch (Pred) {
+    default:
+      break;
+    case FCmpInst::FCMP_OLT:
+    case FCmpInst::FCMP_ULT:
+      return new ICmpInst(ICmpInst::ICMP_SLT, Builder.CreateBitCast(X, IntType),
+                          ConstantInt::getNullValue(IntType));
+    case FCmpInst::FCMP_OGT:
+    case FCmpInst::FCMP_UGT:
+      return new ICmpInst(ICmpInst::ICMP_SGT, Builder.CreateBitCast(X, IntType),
+                          ConstantInt::getNullValue(IntType));
+    case FCmpInst::FCMP_OLE:
+    case FCmpInst::FCMP_ULE:
+      return new ICmpInst(ICmpInst::ICMP_SLE, Builder.CreateBitCast(X, IntType),
+                          ConstantInt::getNullValue(IntType));
+    case FCmpInst::FCMP_OGE:
+    case FCmpInst::FCMP_UGE:
+      return new ICmpInst(ICmpInst::ICMP_SGE, Builder.CreateBitCast(X, IntType),
                           ConstantInt::getNullValue(IntType));
     }
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124150.424388.patch
Type: text/x-patch
Size: 3762 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220422/62323645/attachment.bin>


More information about the llvm-commits mailing list