[llvm] 4827771 - [InstCombine] fold test of equality to 0.0 with bitcast operand

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 26 10:55:10 PDT 2022


Author: Sanjay Patel
Date: 2022-08-26T13:46:11-04:00
New Revision: 482777123427622f15837cdbda97080798f6cc85

URL: https://github.com/llvm/llvm-project/commit/482777123427622f15837cdbda97080798f6cc85
DIFF: https://github.com/llvm/llvm-project/commit/482777123427622f15837cdbda97080798f6cc85.diff

LOG: [InstCombine] fold test of equality to 0.0 with bitcast operand

fcmp oeq/une (bitcast X), 0.0 --> (and X, SignMaskC) ==/!= 0
https://alive2.llvm.org/ce/z/ZKATGN

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index fd452574c9b0..4a0ba31087df 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -6888,6 +6888,25 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
   if (match(Op1, m_AnyZeroFP()) && !match(Op1, m_PosZeroFP()))
     return replaceOperand(I, 1, ConstantFP::getNullValue(OpType));
 
+  // Ignore signbit of bitcasted int when comparing equality to FP 0.0:
+  // fcmp oeq/une (bitcast X), 0.0 --> (and X, SignMaskC) ==/!= 0
+  if (match(Op1, m_PosZeroFP()) &&
+      match(Op0, m_OneUse(m_BitCast(m_Value(X)))) &&
+      X->getType()->getScalarSizeInBits() == OpType->getScalarSizeInBits()) {
+    ICmpInst::Predicate IntPred = ICmpInst::BAD_ICMP_PREDICATE;
+    if (Pred == FCmpInst::FCMP_OEQ)
+      IntPred = ICmpInst::ICMP_EQ;
+    else if (Pred == FCmpInst::FCMP_UNE)
+      IntPred = ICmpInst::ICMP_NE;
+
+    if (IntPred != ICmpInst::BAD_ICMP_PREDICATE) {
+      Type *IntTy = X->getType();
+      const APInt &SignMask = ~APInt::getSignMask(IntTy->getScalarSizeInBits());
+      Value *MaskX = Builder.CreateAnd(X, ConstantInt::get(IntTy, SignMask));
+      return new ICmpInst(IntPred, MaskX, ConstantInt::getNullValue(IntTy));
+    }
+  }
+
   // Handle fcmp with instruction LHS and constant RHS.
   Instruction *LHSI;
   Constant *RHSC;

diff  --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 1d4a2c1083a0..198a71504a56 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1215,8 +1215,8 @@ define i1 @fneg_une_swap(float %p) {
 
 define i1 @bitcast_eq0(i32 %x) {
 ; CHECK-LABEL: @bitcast_eq0(
-; CHECK-NEXT:    [[F:%.*]] = bitcast i32 [[X:%.*]] to float
-; CHECK-NEXT:    [[R:%.*]] = fcmp oeq float [[F]], 0.000000e+00
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 2147483647
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %f = bitcast i32 %x to float
@@ -1226,8 +1226,8 @@ define i1 @bitcast_eq0(i32 %x) {
 
 define <2 x i1> @bitcast_ne0(<2 x i32> %x) {
 ; CHECK-LABEL: @bitcast_ne0(
-; CHECK-NEXT:    [[F:%.*]] = bitcast <2 x i32> [[X:%.*]] to <2 x float>
-; CHECK-NEXT:    [[R:%.*]] = fcmp une <2 x float> [[F]], zeroinitializer
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 2147483647, i32 2147483647>
+; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %f = bitcast <2 x i32> %x to <2 x float>
@@ -1235,6 +1235,8 @@ define <2 x i1> @bitcast_ne0(<2 x i32> %x) {
   ret <2 x i1> %r
 }
 
+; negative test - extra use
+
 define i1 @bitcast_eq0_use(i32 %x) {
 ; CHECK-LABEL: @bitcast_eq0_use(
 ; CHECK-NEXT:    [[F:%.*]] = bitcast i32 [[X:%.*]] to float
@@ -1248,6 +1250,8 @@ define i1 @bitcast_eq0_use(i32 %x) {
   ret i1 %r
 }
 
+; negative test - this could be transformed, but requires a new bitcast
+
 define i1 @bitcast_nonint_eq0(<2 x i16> %x) {
 ; CHECK-LABEL: @bitcast_nonint_eq0(
 ; CHECK-NEXT:    [[F:%.*]] = bitcast <2 x i16> [[X:%.*]] to float
@@ -1259,6 +1263,8 @@ define i1 @bitcast_nonint_eq0(<2 x i16> %x) {
   ret i1 %r
 }
 
+; negative test - wrong predicate
+
 define i1 @bitcast_gt0(i32 %x) {
 ; CHECK-LABEL: @bitcast_gt0(
 ; CHECK-NEXT:    [[F:%.*]] = bitcast i32 [[X:%.*]] to float


        


More information about the llvm-commits mailing list