[PATCH] D159464: Fold comparison of add of zero extended booleans

Mohamed Atef via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 6 06:28:41 PDT 2023


elhewaty created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
elhewaty requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

zext i1 X + zext i1 Y == 1 --> xor i1 X, Y
zext i1 X + zext i1 Y == 0 --> !(or i1 X, Y)


https://reviews.llvm.org/D159464

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
  llvm/test/Transforms/InstCombine/icmp-add.ll


Index: llvm/test/Transforms/InstCombine/icmp-add.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp-add.ll
+++ llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -5,6 +5,36 @@
 
 ; PR1949
 
+define i1 @cvt_icmp_1_to_xor(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_1_to_xor(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT:    ret i1 [[I4]]
+;
+bb:
+  %i = zext i1 %arg to i32
+  %i2 = zext i1 %arg1 to i32
+  %i3 = add nuw nsw i32 %i2, %i
+  %i4 = icmp eq i32 %i3, 1
+  ret i1 %i4
+}
+
+define i1 @cvt_icmp_0_to_nor(i1 %arg, i1 %arg1) {
+; CHECK-LABEL: @cvt_icmp_0_to_nor(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
+; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
+; CHECK-NEXT:    ret i1 [[I4]]
+;
+bb:
+  %i = zext i1 %arg to i32
+  %i2 = zext i1 %arg1 to i32
+  %i3 = add nuw nsw i32 %i2, %i
+  %i4 = icmp eq i32 %i3, 0
+  ret i1 %i4
+}
+
+
 define i1 @test1(i32 %a) {
 ; CHECK-LABEL: @test1(
 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[A:%.*]], -5
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2899,12 +2899,34 @@
                                                    BinaryOperator *Add,
                                                    const APInt &C) {
   Value *Y = Add->getOperand(1);
+  Value *X = Add->getOperand(0);
+
+  // We have two cases to handle here:
+  // 1- (zext i1 X + zext i1 Y) == 1 --> xor i1 X, Y
+  // 2- (zext i1 X + zext i1 Y) == 0 --> !(or i1 X, Y)
+  if (Cmp.isEquality()) {
+    if (match(Add, m_c_Add(m_OneUse(m_ZExt(m_Value(X))),
+                           m_OneUse(m_ZExt(m_Value(Y))))) &&
+        X->getType()->isIntOrIntVectorTy(1) &&
+        Y->getType()->isIntOrIntVectorTy(1) && (C.isZero() || C.isOne())) {
+      Value *Cond = Builder.getFalse();
+      // Case 1:
+      if (C.isOne()) {
+        Cond = Builder.CreateXor(X, Y);
+      } else {
+        // Case 2:
+        Cond = Builder.CreateNot(Builder.CreateOr(X, Y));
+      }
+      return replaceInstUsesWith(Cmp, Cond);
+    }
+    return nullptr;
+  }
+
   const APInt *C2;
-  if (Cmp.isEquality() || !match(Y, m_APInt(C2)))
+  if (!match(Y, m_APInt(C2)))
     return nullptr;
 
   // Fold icmp pred (add X, C2), C.
-  Value *X = Add->getOperand(0);
   Type *Ty = Add->getType();
   const CmpInst::Predicate Pred = Cmp.getPredicate();
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D159464.556021.patch
Type: text/x-patch
Size: 2614 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230906/7fca4872/attachment.bin>


More information about the llvm-commits mailing list